简体   繁体   中英

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

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

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!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM