Search code examples
c#xmlxmlreader

Is it possible to build a dom tree with C# XmlReader only?


I want to build a dom tree with XmlReader over any valid xml string without using class XmlDocument or class XDocument. And I got difficulty in determine whether the element <tank> is the child node of element <plane>. Because Element <plane> doesn't have the end tag. If this difficulty is solved, then I'll be able to generate the Dom tree. Does anyone know how to solve this issue or does anyone know how to build the DOM tree dynamically with XmlReader?

Xml Content:

<?xml version="1.0" encoding="utf-8" ?>
<root>
    <plane visible="false" />
    <tank>
        <weapon name="cannon">equipped</weapon>
    </tank>
    <ship>
        <weapon name="cannon">equipped</weapon>
    </ship>
</root>

Script to Display the Details

XmlReader xr = XmlReader.Create(xmlContent);
while (xr.Read())
{
    Logger.Log(string.Concat("[", xr.NodeType, "][", xr.ValueType, "]", xr.Name, ",(",xr.HasValue,")" + xr.Value));
}

Details

[XmlDeclaration]    [System.String] xml,(True)version="1.0" encoding="utf-8"
[Element]           [System.String] root,(False)
[Element]           [System.String] plane,(False)
[Element]           [System.String] tank,(False)
[Element]           [System.String] weapon,(False)
[Text]              [System.String] ,(True)equipped
[EndElement]        [System.String] weapon,(False)
[EndElement]        [System.String] tank,(False)
[Element]           [System.String] ship,(False)
[Element]           [System.String] weapon,(False)
[Text]              [System.String] ,(True)equipped
[EndElement]        [System.String] weapon,(False)
[EndElement]        [System.String] ship,(False)
[EndElement]        [System.String] root,(False)

Solution

  • The problem here is that the <plane> tag isn't a parent of the <tank> tag - it is a sibling of it. If the <plane> tag needs to be a parent element of the <tank> tag, it needs to wrap it in the xml.

    If it isn't possible for you to change the xml, you can use xr.IsEmptyElement to determine if a tag is self-closed or not, and have custom logic to work around that accordingly.