Search code examples
c#xmlxmlreader

find child element with same name using an XmlReader?


I have the following XML file:

<mall_tree>
    <catalog name="SPECIALS">
        <catalog name="Popular">
            <item id="7004" showmodel="false"/>
            <item id="7005" showmodel="false"/>
            <item id="7002" showmodel="false"/>
            <item id="635" showmodel="false"/>
            <item id="210" showmodel="false"/>
            <item id="531" showmodel="false"/>
            <item id="216" showmodel="false"/>
            <item id="214" showmodel="false"/>
            <item id="590" showmodel="false"/>
            <item id="595" showmodel="false"/>
            <item id="466" showmodel="false"/>
            <item id="175" showmodel="false"/>
            <item id="564" showmodel="false"/>
        </catalog>
        <catalog name="Packs">
            <item id="7004" showmodel="false"/>
            <item id="7002" showmodel="false"/>
            <item id="7001" showmodel="false"/>
            <item id="7003" showmodel="false"/>
            <item id="182" showmodel="false"/>
            <item id="635" showmodel="false"/>
        </catalog>
        <catalog name="Dime Store">
            <item id="688" showmodel="false"/>
            <item id="207" showmodel="false"/>
            <item id="378" showmodel="false"/>
            <item id="488" showmodel="false"/>
            <item id="215" showmodel="false"/>
            <item id="217" showmodel="false"/>
            <item id="461" showmodel="false"/>
            <item id="206" showmodel="false"/>
            <item id="190" showmodel="false"/>
        </catalog>
    </catalog>
    <catalog name="GENERAL">
        <catalog name="Boosts">
            <item id="7002" showmodel="false"/>
            <item id="210" showmodel="false"/>
            <item id="192" showmodel="false"/>
            <item id="635" showmodel="false"/>
            <item id="688" showmodel="false"/>
            <item id="531" showmodel="false"/>
            <item id="530" showmodel="false"/>
            <item id="488" showmodel="false"/>
            <item id="201" showmodel="false"/>
            <item id="197" showmodel="false"/>
            <item id="378" showmodel="false"/>
        </catalog>
        <catalog name="Teleport">
            <item id="207" showmodel="false"/>
            <item id="208" showmodel="false"/>
            <item id="209" showmodel="false"/>
            <item id="191" showmodel="false"/>
        </catalog>
        <catalog name="Crafting">
            <item id="548" showmodel="false"/>
            <item id="549" showmodel="false"/>
            <item id="550" showmodel="false"/>
            <item id="552" showmodel="false"/>
            <item id="553" showmodel="false"/>
            <item id="554" showmodel="false"/>
            <item id="556" showmodel="false"/>
            <item id="557" showmodel="false"/>
            <item id="558" showmodel="false"/>
            <item id="165" showmodel="false"/>
            <item id="166" showmodel="false"/>
            <item id="167" showmodel="false"/>
            <item id="168" showmodel="false"/>
            <item id="169" showmodel="false"/>
            <item id="170" showmodel="false"/>
        </catalog>
    </catalog>
    <catalog name="UPGRADES">
        <catalog name="Utility">
            <item id="7005" showmodel="false"/>
            <item id="215" showmodel="false"/>
            <item id="213" showmodel="false"/>
            <item id="216" showmodel="false"/>
            <item id="214" showmodel="false"/>
            <item id="217" showmodel="false"/>
            <item id="218" showmodel="false"/>
            <item id="219" showmodel="false"/>
            <item id="220" showmodel="false"/>
            <item id="221" showmodel="false"/>
        </catalog>
        <catalog name="Projectile">
            <item id="564" showmodel="false"/>
            <item id="640" showmodel="false"/>
        </catalog>
        <catalog name="Lv1 Gems">
            <item id="451" showmodel="false"/>
            <item id="454" showmodel="false"/>
            <item id="379" showmodel="false"/>
            <item id="382" showmodel="false"/>
            <item id="385" showmodel="false"/>
            <item id="388" showmodel="false"/>
            <item id="391" showmodel="false"/>
            <item id="406" showmodel="false"/>
            <item id="394" showmodel="false"/>
            <item id="409" showmodel="false"/>
            <item id="397" showmodel="false"/>
            <item id="412" showmodel="false"/>
            <item id="400" showmodel="false"/>
            <item id="415" showmodel="false"/>
            <item id="403" showmodel="false"/>
            <item id="418" showmodel="false"/>
            <item id="421" showmodel="false"/>
            <item id="442" showmodel="false"/>
            <item id="427" showmodel="false"/>
            <item id="445" showmodel="false"/>
            <item id="430" showmodel="false"/>
            <item id="448" showmodel="false"/>
            <item id="436" showmodel="false"/>
            <item id="439" showmodel="false"/>
        </catalog>
        <catalog name="Lv3 Gems">
            <item id="7001" showmodel="false"/>
        </catalog>
    </catalog>
    <catalog name="MOUNTS">
        <catalog name="Mount">
            <item id="304" showmodel="false"/>
            <item id="307" showmodel="false"/>
            <item id="305" showmodel="false"/>
        </catalog>
        <catalog name="Umbrella">
            <item id="630" showmodel="false"/>
        </catalog>
    </catalog>
    <catalog name="PETS">
        <catalog name="Talents">
            <item id="357" showmodel="false"/>
            <item id="358" showmodel="false"/>
            <item id="590" showmodel="false"/>
            <item id="593" showmodel="false"/>
            <item id="594" showmodel="false"/>
            <item id="595" showmodel="false"/>
        </catalog>
        <catalog name="Refresh">
            <item id="360" showmodel="false"/>
            <item id="361" showmodel="false"/>
        </catalog>
        <catalog name="Respec">
            <item id="363" showmodel="false"/>
            <item id="364" showmodel="false"/>
            <item id="365" showmodel="false"/>
            <item id="366" showmodel="false"/>
            <item id="367" showmodel="false"/>
        </catalog>
        <catalog name="Energy">
            <item id="461" showmodel="false"/>
        </catalog>
    </catalog>
    <catalog name="FASHION">
        <catalog name="Body">
            <item id="561" showmodel="true"/>
            <item id="566" showmodel="true"/>
            <item id="678" showmodel="true"/>
            <item id="560" showmodel="true"/>
            <item id="565" showmodel="true"/>
            <item id="679" showmodel="true"/>
        </catalog>
        <catalog name="Head">
            <item id="563" showmodel="true"/>
            <item id="568" showmodel="true"/>
            <item id="676" showmodel="true"/>
            <item id="562" showmodel="true"/>
            <item id="567" showmodel="true"/>
            <item id="677" showmodel="true"/>
        </catalog>
        <catalog name="Class">
            <item id="322" showmodel="true"/>
            <item id="308" showmodel="true"/>
            <item id="317" showmodel="true"/>
            <item id="309" showmodel="true"/>
            <item id="318" showmodel="true"/>
            <item id="310" showmodel="true"/>
            <item id="319" showmodel="true"/>
            <item id="311" showmodel="true"/>
            <item id="320" showmodel="true"/>
            <item id="313" showmodel="true"/>
            <item id="321" showmodel="true"/>
            <item id="312" showmodel="true"/>
            <item id="323" showmodel="true"/>
            <item id="314" showmodel="true"/>
            <item id="324" showmodel="true"/>
            <item id="315" showmodel="true"/>
            <item id="325" showmodel="true"/>
            <item id="316" showmodel="true"/>
            <item id="341" showmodel="true"/>
            <item id="326" showmodel="true"/>
            <item id="331" showmodel="true"/>
            <item id="327" showmodel="true"/>
            <item id="337" showmodel="true"/>
            <item id="328" showmodel="true"/>
            <item id="338" showmodel="true"/>
            <item id="329" showmodel="true"/>
            <item id="339" showmodel="true"/>
            <item id="330" showmodel="true"/>
            <item id="340" showmodel="true"/>
            <item id="333" showmodel="true"/>
            <item id="342" showmodel="true"/>
            <item id="334" showmodel="true"/>
            <item id="343" showmodel="true"/>
            <item id="335" showmodel="true"/>
            <item id="332" showmodel="true"/>
            <item id="336" showmodel="true"/>
        </catalog>
        <catalog name="Accessory">
            <item id="622" showmodel="true"/>
            <item id="621" showmodel="true"/>
            <item id="624" showmodel="true"/>
            <item id="623" showmodel="true"/>
            <item id="544" showmodel="true"/>
            <item id="541" showmodel="true"/>
            <item id="486" showmodel="true"/>
            <item id="303" showmodel="true"/>
            <item id="299" showmodel="true"/>
            <item id="301" showmodel="true"/>
            <item id="302" showmodel="true"/>
            <item id="352" showmodel="true"/>
            <item id="490" showmodel="true"/>
            <item id="489" showmodel="true"/>
            <item id="298" showmodel="true"/>
        </catalog>
        <catalog name="Utility">
            <item id="466" showmodel="false"/>
            <item id="465" showmodel="false"/>
            <item id="625" showmodel="false"/>
            <item id="464" showmodel="false"/>
            <item id="547" showmodel="false"/>
        </catalog>
    </catalog>
    <catalog name="SOCIAL">
        <catalog name="Guild">
            <item id="175" showmodel="false"/>
            <item id="176" showmodel="false"/>
            <item id="177" showmodel="false"/>
            <item id="179" showmodel="false"/>
            <item id="178" showmodel="false"/>
        </catalog>
        <catalog name="Marriage">
            <item id="7003" showmodel="false"/>
            <item id="182" showmodel="false"/>
            <item id="462" showmodel="false"/>
            <item id="463" showmodel="false"/>
            <item id="180" showmodel="false"/>
            <item id="181" showmodel="false"/>
            <item id="190" showmodel="false"/>
        </catalog>
        <catalog name="Friends">
            <item id="193" showmodel="false"/>
            <item id="194" showmodel="false"/>
            <item id="195" showmodel="false"/>
            <item id="196" showmodel="false"/>
            <item id="528" showmodel="false"/>
            <item id="529" showmodel="false"/>
        </catalog>
        <catalog name="Chat">
            <item id="487" showmodel="false"/>
            <item id="459" showmodel="false"/>
            <item id="206" showmodel="false"/>
        </catalog>
        <catalog name="Grafitti">
            <item id="202" showmodel="false"/>
            <item id="203" showmodel="false"/>
            <item id="204" showmodel="false"/>
            <item id="205" showmodel="false"/>
        </catalog>
        <catalog name="Tours">
            <item id="187" showmodel="false"/>
            <item id="184" showmodel="false"/>
            <item id="188" showmodel="false"/>
            <item id="185" showmodel="false"/>
            <item id="189" showmodel="false"/>
            <item id="186" showmodel="false"/>
        </catalog>
    </catalog>
</mall_tree>

I am trying to take the <catalog name="SPECIALS"> node and get all of the other <catalog> nodes that are nested inside of it. I'm using XMLTextReader to read the file, is there possibly a better way? Here is the current code I'm using.

XmlTextReader reader = new XmlTextReader(filePath);
reader.ReadToFollowing("catalog");
    do
    {
        Console.WriteLine("Name: {0}", reader.GetAttribute("name"));
    }
    while (reader.ReadToFollowing("catalog"));

Solution

  • This will get you the list of descendant "catalog" nodes:

    XDocument xDoc = XDocument.Load("yourFile.xml");
    
    var doc = xDoc.Descendants("catalog")
                  .Where(x => x.Attribute("name").Value == "SPECIALS")
                  .Select(x => x.Nodes())
                  .SelectMany(x => x.ToList())
                  .ToList();
    

    The output is 3 XNode instances, for Popular, Packs, and Dime Store.

    To print them out to the console:

    foreach (var d in doc.OfType<XElement>())
        Console.WriteLine("Name: {0}", d.Attribute("name").Value);