Sean C.
Sean C.

Reputation: 1603

using XmlReader to get child nodes without knowing their names(in .net)

How do I get the the top level child nodes(unknownA) of root node with XmlReader in .net? Because their names are unknown, ReadToDescendant(string) and ReadToNextSibling(string)won't work.

<root>
    <unknownA/>
    <unknownA/>
    <unknownA>
        <unknownB/>
        <unknownB/>
    </unknownA>
    <unknownA/>
    <unknownA>
        <unknownB/>
        <unknownB>
            <unknownC/>
            <unknownC/>
        </unknownB>
    </unknownA>
    <unknownA/>
</root>

Upvotes: 1

Views: 2415

Answers (1)

dbc
dbc

Reputation: 116741

You can walk through the file using XmlReader.Read(), checking the current Depth against the initial depth, until reaching an element end at the initial depth, using the following extension method:

public static class XmlReaderExtensions
{
    public static IEnumerable<string> ReadChildElementNames(this XmlReader xmlReader)
    {
        if (xmlReader == null)
            throw new ArgumentNullException();
        if (xmlReader.NodeType == XmlNodeType.Element && !xmlReader.IsEmptyElement)
        {
            var depth = xmlReader.Depth;
            while (xmlReader.Read())
            {
                if (xmlReader.Depth == depth + 1 && xmlReader.NodeType == XmlNodeType.Element)
                    yield return xmlReader.Name;
                else if (xmlReader.Depth == depth && xmlReader.NodeType == XmlNodeType.EndElement)
                    break;
            }
        }
    }

    public static bool ReadToFirstElement(this XmlReader xmlReader)
    {
        if (xmlReader == null)
            throw new ArgumentNullException();
        while (xmlReader.NodeType != XmlNodeType.Element)
            if (!xmlReader.Read())
                return false;
        return true;
    }
}

Then it could be used as follows:

        var xml = GetXml(); // Your XML string

        using (var textReader = new StringReader(xml))
        using (var xmlReader = XmlReader.Create(textReader))
        {
            xmlReader.ReadToFirstElement();
            var names = xmlReader.ReadChildElementNames().ToArray();
            Console.WriteLine(string.Join("\n", names));
        }

Upvotes: 1

Related Questions