user3375390
user3375390

Reputation: 99

Getting the count of xml elements under an XML Node

I am looking to get the count of elements under a particular node in an XML file.

The file will look something like the following

<Return>
  <ReturnHeader>   
  </ReturnHeader>
  <ReturnData documentCnt="8">
    <file1></file1>   
    <file2></file2>   
    <file3></file3>   
    <file4></file4>   
    <file5></file5>   
    <file6></file6>   
    <file7></file7>   
    <file8></file8>
  </ReturnData>
<ParentReturn>
  <ReturnHeader> 
  </ReturnHeader>
  <ReturnData documentCnt="6">
    <file1></file1>   
    <file2></file2>   
    <file3></file3>   
    <file4></file4>   
    <file5></file5>   
    <file6></file6>     
  </ReturnData>
</ParentReturn>
<SubsidiaryReturn>
  <ReturnHeader>
  </ReturnHeader>
  <ReturnData documentCnt="3">
    <file1></file1>   
    <file2></file2>   
    <file3></file3>     
  </ReturnData>
</SubsidiaryReturn>
</Return>

I need to parse this xml file for the ReturnData node (which is located in multiple locations in the file as you can see) and get the count of the elements underneath it.

For example - Under Return\ReturnData the count has to be 8 - Under Return\ParentReturn\ReturnData the count has to be 6 - Under Return\SubsidiaryReturn\ReturnData the count has to be 3

The attribute documentCnt should actually give me the right count but the xml document that gets created will have discrepancies and hence I will need to parse this xml file and check if the value in the documentCnt attribute matches the number of elements under the ReturnData node.

Upvotes: 0

Views: 715

Answers (1)

Alex
Alex

Reputation: 13224

Using the problem description you gave of:

The attribute documentCnt should actually give me the right count but the xml document that gets created will have discrepancies and hence I will need to parse this xml file and check if the value in the documentCnt attribute matches the number of elements under the ReturnData node.

This could be solved in a single step if you were to use a simple select statement on the "ReturnData" element, as in:

public static void Main(params string[] args)
{
    // test.xml contains OPs example xml.
    var xDoc = XDocument.Load(@"c:\temp\test.xml");

    // this will return an anonymous object for each "ReturnData" node.
    var counts = xDoc.Descendants("ReturnData").Select((e, ndx) => new
    {
        // although xml does not have specified order this will generally
        // work when tracing back to the source.
        Index = ndx,

        // the expected number of child nodes.
        ExpectedCount = e.Attribute("documentCnt") != null ? int.Parse(e.Attribute("documentCnt").Value) : 0,

        // the actual child nodes.
        ActualCount = e.DescendantNodes().Count()
    });

    // now we can select the mismatches
    var mismatches = counts.Where(c => c.ExpectedCount != c.ActualCount).ToList();

    // and the others must therefore be the matches.
    var matches = counts.Except(mismatches).ToList();

    // we expect 3 matches and 0 mismatches for the sample xml.
    Console.WriteLine("{0} matches, {1} mismatches", matches.Count, mismatches.Count);
    Console.ReadLine();
}

Upvotes: 1

Related Questions