none
XML file to xDocument with variable element names RRS feed

  • Question

  • Hello,
     
    how can I read the file into xDocument if panel index and index are flexible.
    How I get this inside a object?
        <index1 ref1="0001" ref2="001" ref3="6MIN8F">0607777770001</index1>
    Request
     GetValue(panelnr, index)
     GetValue(2, 4)
    Response
        060777777 0002 002
    <order>
      060777777
      <model>203 777-01 V05</model>
      <count>4</count>
      <panel1>
        <index1 ref1="0001" ref2="001" ref3="6MIN8F">0607777770001</index1>
        <index2 ref1="0001" ref2="001" ref3="6MIN8F">0607777770001</index2>
        <index3 ref1="0001" ref2="001" ref3="6MIN8F">060777777 0001 001</index3>
        <index4 ref1="0001" ref2="002" ref3="6MIN8F">060777777 0001 002</index4>
        <index5 ref1="0001" ref2="003" ref3="6MIN8F">060777777 0001 003</index5>
      </panel1>
      <panel2>
        <index1 ref1="0002" ref2="001" ref3="6MIN8F">0607777770002</index1>
        <index2 ref1="0002" ref2="001" ref3="6MIN8F">0607777770002</index2>
        <index3 ref1="0002" ref2="001" ref3="6MIN8F">060777777 0002 001</index3>
        <index4 ref1="0002" ref2="002" ref3="6MIN8F">060777777 0002 002</index4>
        <index5 ref1="0002" ref2="003" ref3="6MIN8F">060777777 0002 003</index5>
      </panel2>
      <panel3>
        <index1 ref1="0003" ref2="001" ref3="6MIN8F">0607777770003</index1>
        <index2 ref1="0003" ref2="001" ref3="6MIN8F">0607777770003</index2>
        <index3 ref1="0003" ref2="001" ref3="6MIN8F">060777777 0003 001</index3>
        <index4 ref1="0003" ref2="002" ref3="6MIN8F">060777777 0003 002</index4>
        <index5 ref1="0003" ref2="003" ref3="6MIN8F">060777777 0003 003</index5>
      </panel3>
      <panel4>
        <index1 ref1="0004" ref2="001" ref3="6MIN8F">0607777770004</index1>
        <index2 ref1="0004" ref2="001" ref3="6MIN8F">0607777770004</index2>
        <index3 ref1="0004" ref2="001" ref3="6MIN8F">060777777 0004 001</index3>
        <index4 ref1="0004" ref2="002" ref3="6MIN8F">060777777 0004 002</index4>
        <index5 ref1="0004" ref2="003" ref3="6MIN8F">060777777 0004 003</index5>
      </panel4>
    </order>
    
    I want only this value.
    <works_order>
      060418001
     
    I got it all, see screenshot, why?
    //<works_order>
     // 060418001
     // <model>203 569-01 V05</model>
     // <count>3</count>
     // <panel1>
     //   <index1 ref1="0001" ref2="001" ref3="6MIN8F">0604180010001</index1>
     //   <index2 ref1="0001" ref2="001" ref3="6MIN8F">0604180010001</index2>
     //   <index3 ref1="0001" ref2="001" ref3="6MIN8F">060418001 0001 001</index3>
     //   <index4 ref1="0001" ref2="002" ref3="6MIN8F">060418001 0001 002</index4>
    
                bool ret = false;
                try
                {
                    //XDoc = XDocument.Parse(xmlContent);
                    XDoc = XDocument.Load("..\\..\\Order.xml");
    
                    Order = XDoc.Element("works_order")?.Value;
                    Panel = XDoc.Element("works_order")?.Element("panel1")?.Value;
    				
    
    ListPropertiesIndex = (from e in XDoc.XPathSelectElements("//panel1")
    		   select new PropertyIndex
    		   {
    			
    			   Index = e.Element("index1")?.Value,   // I need here a index
    			                                         // But i do not know how much.
    			   //IndexValue = e.Attribute("index1")?.Value,
    			   Ref1 = e.Attribute("ref1")?.Value,
    			   Ref2 = e.Attribute("ref2")?.Value,
    			   Ref3 = e.Attribute("ref3")?.Value,
    
    		   }).ToList();
      

    With best regards Markus

    Friday, June 22, 2018 3:28 PM

Answers

  • There is no functionality in the XML classes to do anything with the Value you get back but there are the standard string functions. If you want to strip off the newlines and get the first value then Split should do the trick.

    //Using a dummy variable here, use the actual XML value instead
    var value = "\n5532525   \n  3254235";
    
    var firstValue = value.Split(new[] { '\n', ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries).FirstOrDefault()?.Trim();


    Michael Taylor http://www.michaeltaylorp3.net

    Tuesday, June 26, 2018 4:54 PM
    Moderator

All replies

  • Please provide a more clear example of your input and what you want back. You show some code that calls GetPanel(2,4) but you don't clarify what that 2 and 4 represent. In the XML you posted there is no mention of the value that you are expecting back (060418001). Where did it come from?

    If we are to assume, based upon your second example, that 2 is the panel and 4 is the index then you can use those in your queries.

    string GetValue ( XDocument xml, int panel, int index )
    {
       //Not tested
       var panel = XDoc.Element("works_order")?.Element($"panel{panel}");
    
       var element = panel.Element($"index{index}");
       ...
    }


    Michael Taylor http://www.michaeltaylorp3.net

    Friday, June 22, 2018 5:29 PM
    Moderator
  • Hello,

    back

    I want to back only the number 060418001 not all.

    In my example. OK, maybe I  need not the Value?

    With best regards Markus





    Saturday, June 23, 2018 10:24 AM
  • Use the Value property to get the value between the start and end elements. For an element that has children it will be the children but in your XML if you were to use this on one of the index elements like I wrote then it would be the value you had asked for. Given your earlier example of (2,4) it would be the value of panel2's index4 - 060777777 0002 002.

    string GetValue ( XDocument xml, int panel, int index )
    {
       //Not tested
       var panel = XDoc.Element("works_order")?.Element($"panel{panel}");
    
       var element = panel.Element($"index{index}");
     
       //Get the value between the element start and end tags
       return element?.Value;
    }

    Give this code a shot and let me know if you get a different value instead.


    Michael Taylor http://www.michaeltaylorp3.net

    Saturday, June 23, 2018 4:07 PM
    Moderator
  • Hello CoolDadTx,
    var workOrder = XDoc.Element("works_order");
    // ** Works not.
    // ** Only this issue is open.

    workorder

    // ** Works well - Thanks.
    string retTest = GetValue(XDoc, 2, 4);
    Order = XDoc.Element("works_order")?.Element("panel1")?.Value;
    ResponseToRequestID = XDoc.Element("works_order")?.Element("panel1")?.Element("index1").Attribute("ref3").Value;
    
    
    IEnumerable<XElement> panels = XDoc.XPathSelectElements("/works_order/*[starts-with(name(), 'panel')]");
    foreach (XElement panel in panels)
    {
    	Console.WriteLine(panel.Name.LocalName);
    	IEnumerable<XElement> indices = panel.XPathSelectElements("*[starts-with(name(), 'index')]");
    	foreach (XElement index in indices)
    	{
    		Console.WriteLine("\t" + index.Name.LocalName);
    	}
    }
    
    string GetValue(XDocument xml, int panel, int index)
    {
    	var panelIndex = XDoc.Element("works_order")?.Element($"panel{panel}");
    
    	var element = panelIndex.Element($"index{index}");
    
    	//Get the value between the element start and end tags
    	return element?.Value;
    }
    With best regards Markus

    Monday, June 25, 2018 4:39 PM
  • So the issue now is that you are trying to get the text in the root of your work_orders element?

    If so then Value is correct but it'll be the raw format with the newline. Just strip those off.

    //Trim any leading/trailing spaces, tabs and newlines
    var workOrder2 = XDoc.Element("works_order").Value.Trim(new [] { ' ', '\t', '\n' });


    Michael Taylor http://www.michaeltaylorp3.net

    Monday, June 25, 2018 4:51 PM
    Moderator
  • Hello,
    does not work as expected, are there no members?
    Do I have to analyze this myself? \n5532525 \n 3254235

     Makes 5532525 \n 3254235

    But I need only 5532525

    With best regards Markus

    Tuesday, June 26, 2018 4:37 PM
  • There is no functionality in the XML classes to do anything with the Value you get back but there are the standard string functions. If you want to strip off the newlines and get the first value then Split should do the trick.

    //Using a dummy variable here, use the actual XML value instead
    var value = "\n5532525   \n  3254235";
    
    var firstValue = value.Split(new[] { '\n', ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries).FirstOrDefault()?.Trim();


    Michael Taylor http://www.michaeltaylorp3.net

    Tuesday, June 26, 2018 4:54 PM
    Moderator

  • Hello CoolDadTx,
    works now well. Thanks.
    ok
     
     With best regards Markus
    Wednesday, June 27, 2018 4:22 PM