none
Use LINQ to extract values from repeating nodes in XDocument RRS feed

  • Question

  • Hi all,

    I have an XDocument that looks like this:

    <MyFile>
      <ZFH>
        <ZFH_1_ProjectName>myProject</ZFH_1_ProjectName>
        <ZFH_2>
          <ZFHData_1>A</ZFHData_1>
          <ZFHData_2>B</ZFHData_2>
        </ZFH_2>
        <ZFH_2>
          <ZFHData_1>C</ZFHData_1>
          <ZFHData_2>D</ZFHData_2>
        </ZFH_2>
      </ZFH>
      <ZFH>
        <ZFH_1_ProjectName>myOthrProject</ZFH_1_ProjectName>
        <ZFH_2>
          <ZFHData_1>E</ZFHData_1>
          <ZFHData_2>F</ZFHData_2>
        </ZFH_2>
        <ZFH_2>
          <ZFHData_1>G</ZFHData_1>
          <ZFHData_2>H</ZFHData_2>
        </ZFH_2>
      </ZFH>
    </MyFile>

    The <ZFH> node can repeat several times, and inside it the <ZFH_2> node is also a repeatable node.

    I want to extract all values from <ZFHData_1> for a certain project, such as "myProject". I expect to get "A" and "C".

    I tried:

    XDocument xdoc = XDocument.Load("myDocument.xml"); var col = ( from c in xdoc.Descendants("ZFH_2") select c.Element("ZFHData_1").Value ).Distinct();

    This returns A, C, E, G since there is no filtering on project name, no surprise here!

    var col =
        (
        from c in xdoc.Descendants("ZFH")
        where c.Element("ZFH_1_ProjectName").Value   == "myProject"
        select c.Element("ZFH_2").Element("ZFHData_1")
        ).Distinct(); 

    This returns only A and NOT C which I also expect to see!

    What am I doing wrong here? Any help  greatly appreciated!

    Thanks

    Claudiu




    • Edited by ClaudiuH Thursday, January 3, 2013 10:31 PM
    Thursday, January 3, 2013 10:23 PM

Answers

  • CHRider :

    Does this help ?

     XDocument objDoc = XDocument.Load(@"C:\data.xml");
                var query = objDoc.Root.Descendants("ZFH").Where(x => x.Element("ZFH_1_ProjectName").Value == "myProject").Descendants("ZFHData_1").ToList();
                foreach (var x in query)
                {
                    Console.WriteLine(x.Value);
                }

    • Marked as answer by ClaudiuH Friday, January 4, 2013 6:12 AM
    Friday, January 4, 2013 12:47 AM

All replies

  • CHRider :

    Does this help ?

     XDocument objDoc = XDocument.Load(@"C:\data.xml");
                var query = objDoc.Root.Descendants("ZFH").Where(x => x.Element("ZFH_1_ProjectName").Value == "myProject").Descendants("ZFHData_1").ToList();
                foreach (var x in query)
                {
                    Console.WriteLine(x.Value);
                }

    • Marked as answer by ClaudiuH Friday, January 4, 2013 6:12 AM
    Friday, January 4, 2013 12:47 AM
  • It definitely does help :)

    Thanks Venkat786, marked as answer.


    Another question: how do I use XPath with XDocument to accomplish the same task.

    So far I used:

    var query =
     (
      from c in xdoc.XPathSelectElements ("//MyFile/ZFH/ZFH_2/ZFHData_1")
      select c.Value 
     ).Distinct().ToList();

    This returns A, C, E, and G. How do I filter on ProjectName?

    I used:

    var query =
     (
      from c in xdoc.XPathSelectElements("//ZFH") 
      where c.Element("ZFH_1_ProjectName").Value == "Project_1"
      from s in c.XPathSelectElements("//ZFH/ZFH_2/ZFHData_1")
      select s.Value
     ).Distinct().ToList(); 

    But it doesn't return just the values for Project_1.

    Any ideas?

    Thanks

    Claudiu



    • Edited by ClaudiuH Friday, January 11, 2013 9:10 PM
    Friday, January 4, 2013 6:12 AM