Search code examples
c#xmlreader

XMLReader read to next sibling of unknown type


I understand how we can use a code sample like the following..

public class Sample
{
    public static void Main()
    {
        using (XmlReader reader = XmlReader.Create("books.xml"))
        {
            reader.ReadToFollowing("book");
            do
            {
                Console.WriteLine("Name ", reader.GetAttribute("Name"));
            } while (reader.ReadToNextSibling("book"));
        }
    }
}

and this will read every sibling of type "book". So in the xml structure like this one below it would work great..

<Section>
       <book Name="Titan Quest 1"/>
       <book Name="Titan Quest 2"/>
       <book Name="Adventure Willy"/>
       <book Name="Mr. G and the Sandman"/>
       <book Name="Terry and Me"/>
</Section>

But lets say your siblings are not always of type book.. Inside section, we can have book, cd, dvd, or vhs so the xml may look something like this

<Section>
       <cd Name="Titan Quest 1"/>
       <book Name="Titan Quest 2"/>
       <vhs Name="Adventure Willy"/>
       <cd Name="Mr. G and the Sandman"/>
       <dvd Name="Terry and Me"/>
</Section>

I want to write a method that will give me the Name attribute regardless of what sibling type it is.. Using the above code I would only get [Titan Quest 2]. Can this be done? Thanks!


Solution

  • Using this code with XDocument will get all the values from the attributes:

     var document = XDocument.Load("test.xml");
    
     var bookValues = document.XPathSelectElement("Section")
           .Descendants()
           .Select(x => x.Attribute("Name").Value);
    

    Or using XmlReader to get all the attribute values:

    List<String> values = new List<string>();
    using (var xmlreader = XmlReader.Create("test.xml"))
    {
        xmlreader.ReadToDescendant("Section");
        while (xmlreader.Read())
        {
            if (xmlreader.IsStartElement())
            {
                values.Add(xmlreader.GetAttribute("Name"));
            }
        }
    }