Lockie
Lockie

Reputation: 77

C# - XML, Counting the number of specific elements within other elements

I have an XML which I'm loading into my C# program. What I'd like to achieve is to count the number of "army" elements within each "alliance" element.

Here's an example where each "alliance" contains three "army" elements. So the result I'd like to achieve is to have two variables with the result of 3.

<?xml version="1.0"?>
<battle>
  <alliance id="0">
    <army>
      <faction>factionName</faction>
      <unit>
        <unit_type type="unit_A" />
        <general>
          <commander_record_key>commanderName</commander_record_key>
        </general>
        <unit_capabilities>
          <special_ability>abilityName</special_ability>
        </unit_capabilities>
      </unit>
      <unit>
        <unit_type type="unit_A" />
        <unit_capabilities>
          <special_ability>abilityName</special_ability>
        </unit_capabilities>
      </unit>
      <unit>
        <unit_type type="unit_A" />
        <unit_capabilities>
          <special_ability>abilityName</special_ability>
          <special_ability>abilityName</special_ability>
        </unit_capabilities>
      </unit>
    </army>
    <army>
      <faction>factionName</faction>
      <unit>
        <unit_type type="unit_A" />
        <general>
          <commander_record_key>commanderName</commander_record_key>
        </general>
        <unit_capabilities>
          <special_ability>abilityName</special_ability>
          <special_ability>abilityName</special_ability>
        </unit_capabilities>
      </unit>
      <unit>
        <unit_type type="unit_B" />
        <unit_capabilities>
          <special_ability>abilityName</special_ability>
        </unit_capabilities>
      </unit>
      <unit>
        <unit_type type="unit_B" />
        <unit_capabilities>
          <special_ability>abilityName</special_ability>
          <special_ability>abilityName</special_ability>
        </unit_capabilities>
      </unit>
    </army>
    <army>
      <faction>factionName</faction>
      <unit>
        <unit_type type="unit_C" />
        <general>
          <commander_record_key>commanderName</commander_record_key>
        </general>
        <unit_capabilities>
          <special_ability>abilityName</special_ability>
          <special_ability>abilityName</special_ability>
        </unit_capabilities>
      </unit>
      <unit>
        <unit_type type="unit_C" />
        <unit_capabilities>
          <special_ability>abilityName</special_ability>
        </unit_capabilities>
      </unit>
      <unit>
        <unit_type type="unit_C" />
        <unit_capabilities>
          <special_ability>abilityName</special_ability>
        </unit_capabilities>
      </unit>
    </army>
    <victory_condition>
      <kill_or_rout_enemy />
    </victory_condition>
  </alliance>
  <alliance id="1">
    <army>
      <faction>factionName</faction>
      <unit>
        <unit_type type="unit_F" />
        <general>
          <commander_record_key>commanderName</commander_record_key>
        </general>
        <unit_capabilities>
          <special_ability>abilityName</special_ability>
        </unit_capabilities>
      </unit>
      <unit>
        <unit_type type="unit_F" />
        <unit_capabilities>
          <special_ability>abilityName</special_ability>
        </unit_capabilities>
      </unit>
      <unit>
        <unit_type type="unit_F" />
        <unit_capabilities>
          <special_ability>abilityName</special_ability>
        </unit_capabilities>
      </unit>
    </army>
    <army>
      <faction>factionName</faction>
      <unit>
        <unit_type type="unit_F" />
        <general>
          <commander_record_key>commanderName</commander_record_key>
        </general>
        <unit_capabilities>
          <special_ability>abilityName</special_ability>
        </unit_capabilities>
      </unit>
      <unit>
        <unit_type type="unit_F" />
        <unit_capabilities>
          <special_ability>abilityName</special_ability>
        </unit_capabilities>
      </unit>
      <unit>
        <unit_type type="unit_F" />
        <unit_capabilities>
          <special_ability>abilityName</special_ability>
        </unit_capabilities>
      </unit>
    </army>
    <army>
      <faction>factionName</faction>
      <unit>
        <unit_type type="unit_F" />
        <general>
          <commander_record_key>commanderName</commander_record_key>
        </general>
        <unit_capabilities>
          <special_ability>abilityName</special_ability>
        </unit_capabilities>
      </unit>
      <unit>
        <unit_type type="unit_F" />
        <unit_capabilities>
          <special_ability>abilityName</special_ability>
        </unit_capabilities>
      </unit>
      <unit>
        <unit_type type="unit_F" />
        <unit_capabilities>
          <special_ability>abilityName</special_ability>
        </unit_capabilities>
      </unit>
    </army>
    <victory_condition>
      <kill_or_rout_enemy />
    </victory_condition>
  </alliance>
</battle>

Can you help? Many Thanks

Upvotes: 0

Views: 36

Answers (2)

Andrew Truckle
Andrew Truckle

Reputation: 19207

An alternative could be done with XmlDocument and SelectNodes:

List<int> listCount = new List<int>();
XmlDocument docXMLs = new XmlDocument();
docXML.Load("path to file.xml");

XmlNodeList listAlliance = docXML.SelectNodes("Battle/Alliance");
foreach(XmlNode nodeAlliance in listAlliance )
{
    XmlNodeList listArmy = nodAlliance.SelectNodes("Army");
    listCount.Add(listArmy.Count);
}

Please note that I have not tried the above code and there may be a more efficient way to do it. If the answer can be improved then I appreciate any constructive comments!

Upvotes: 1

Hari Prasad
Hari Prasad

Reputation: 16986

You could use Linq to Xml and query for descendants and elements as below.

    XDocument doc = XDocument.Load(filename);


    var results = doc.Descendants("alliance")                                
                     .Select(g=> 
                             new 
                             {
                                 ID = g.Attribute("id").Value, 
                                 ArmyCount =   g.Elements("army").Count() 
                             });

Check this demo

Upvotes: 2

Related Questions