I want to read a XML hierarchy into a tree of in-memory objects. The XML tree could have n-levels of children. I do not know the exact number. My in-memory objects have a ch
Take a look at XmlTextReader and at the package System.Xml. This articles will help you too:
Either way, you have to know the node name to parse the hierarchy at least you have to have a definition. IMHO, XElement
is the only sort of generic XML
parser around. For instance, you have a XML like this:
<module name="core">
<modules>
<module name="xml">
<modules>
<module name="reader" />
<module name="writer" />
</modules>
</module>
<module name="json">
<modules>
<module name="serializer" />
<module name="deserializer" />
</modules>
</module>
</modules>
</module>
As I said earlier, you should have some definitions like the root node
must the hierarchical element name and the children container must be root node name + s
. This is one simple way that you can allow your users to specify any node names they wish but with some constraints.
You may parse the XML
using XElement
like this:
XElement xElement = XElement.Load(@"path\to\your\xml\file");
string rootNodeName = xElement.Name.LocalName;
IEnumerable<XElement> xElements = xElement.Descendants(rootNodeName + "s");
And of course you can Linq
the xElements
and to parse the hierarchy you can recur to build your tree control.
You may take a kick start on xElement with these links below:
Hope this helped.
I believe it is possible to achieve what you want to achieve. I'd do it something like this:
class GenericNode
{
private List<GenericNode> _Nodes = new List<GenericNode>();
private List<GenericKeyValue> _Attributes = new List<GenericKeyValue>();
public GenericNode(XElement Element)
{
this.Name = Element.Name;
this._Nodes.AddRange(Element.Elements()
.Select(e => New GenericNode(e));
this._Attributes.AddRange(
Element.Attributes()
.Select(a => New GenericKeyValue(a.Key, a.Value))
}
public string Name { get; private set; }
public IEnumerable<GenericNode> Nodes
{
get
{
return this._Nodes;
}
}
public IEnumerable<GenericKeyValue> Attributes
{
get
{
return this._Attributes;
}
}
}
class GenericKeyValue
{
public GenericKeyValue(string Key, string Value)
{
this.Key = Key;
this.Value = Value;
}
public string Key { get; set; }
public string Value { get; set; }
}
Then you simply:
XElement rootElement = XElement.Parse(StringOfXml); // or
XElement rootElement = XElement.Load(FileOfXml);
GenericNode rootNode = new GenericRode(rootElement);
I would just load it into XmlDocument
and then build the tree going through XmlNodes
.
Like this?
using System.Xml ;
using System.IO;
class Program
{
static void Main( string[] args )
{
using ( Stream inputStream = OpenXmlStream() )
{
XmlDocument document = new XmlDocument() ;
document.Load( inputStream ) ;
Process( document ) ;
}
}
static Stream OpenXmlStream()
{
// provide an input stream for the program
}
static void Process( XmlDocument document )
{
// do something useful here
}
}