0

I've been researching a lot of XML parsing and serializing methods from MSDN. Looking at Linq and XSD.exe there doesn't seem to be a golden solution that stands out as the one I'm looking for.

My question is what is the best method for this, if it exists.

Let's say I have a XML of arbitrary complexity. One that could be satisfiable by classes such as these, assume they are substantial.

    public class nameVal
    {
        string name { get; set; }
        object value { get; set; }
    }
    public class node
    {
        nameVal self { get; set; }
        List<nameVal> properties { get; set; }
        List<node> children { get; set; }
    };

How would one, from the source of a string or file and using c# and MSDN Libraries achieve this. Some arbitrary way like, foreach(var prop in node) trunk.properties.add(prop)

I've read through a dozen posts here and articles around the web, but I haven't found a way to do this without precursor knowledge of the XML, or an XSD schema created from the XML. I just found it really odd that there wasn't an arbitrary parsing method for putting an XML document into a generic iterable data structure.

So... methods, libraries, the reason this doesn't exist, any information would be really good.

Aage Torleif
  • 1,907
  • 1
  • 20
  • 37

3 Answers3

2

If I understand your question correctly, you want to map any xml to your classes. Here is my try:

var nodes = ParseXml(XDocument.Load(filename).Root);

node ParseXml(XElement root)
{
    var node = new node();

    node.self = new nameVal() { name = root.Name.LocalName, value = (string)root };

    node.properties = root.Attributes()
                          .Select(a => new nameVal() { name = a.Name.LocalName, value = a.Value })
                          .ToList();

    node.children = root.Elements()
                        .Select(e => ParseXml(e))
                        .ToList();

    return node;
}
EZI
  • 15,209
  • 2
  • 27
  • 33
0

There are two possible approaches that I can think of.

The first way would be to infer the XML schema from the XML itself, and then code-generate C# classes from that schema. We already know this is possible, because XSD.EXE can infer a schema from an XML file.

The second way would be to parse the XML and populate an ExpandoObject. This would be the preferred method, if the XML is totally fluid in its structure (i.e. it has an arbitrary schema). Code would look something like this:

public static IEnumerable<dynamic> GetExpandoFromXml(string file, string descendantid)
{
    var expandoFromXml = new List<dynamic>();

    var doc = XDocument.Load(file);
    var nodes = doc.Root.Descendants(descendantid);

    foreach (var element in doc.Root.Descendants(descendantid))
    {
        dynamic expandoObject = new ExpandoObject();
        var dictionary = expandoObject as IDictionary<string, object>;
        foreach (var child in element.Descendants())
        {
            if (child.Name.Namespace == "")
                dictionary[child.Name.ToString()] = child.Value.Trim();
        }
        yield return expandoObject;
    }
}

http://phejndorf.wordpress.com/2011/11/20/using-expandoobject-dynamic-with-xml-data/

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
0

There are several different supported ways of XML in C#, but no single best answer for an hypothetical.

If you want real serialization, i.e. mapping the XML into instances of classes you define, you will need to modify your classes (for example, the properties need to be declared public) and members with a type of object are tricky (how would the deserializer know what type to put there?) This approach requires embedding knowledge of the structure of the XML into the classes, which doesn't sound like what you want.

A more generic solution, these approaches use framework-defined classes for the XML nodes and values, not classes you define. Common choices for this include the DOM-like classes in the System.XML namespace, or newer ones more suited to Linq style processing in the System.Xml.Link namespace. There are good StackOverflow articles about choosing between these options, like XDocument or XmlDocument .

But with the generic approaches, the XML tags and attributes don't map directly to C# property names and collections, as I think you may be looking for. Instead you have to use some methods on the framework class to select what data you want, e.g. XmlDocument has a SelectSingleNode() method that can be used to extract specific data using an XPath query. This results in knowledge of the structure of the XML being limited to the XPath string, rather than embedded in code.

Hope that helps you clarify your question and get it answered.

Community
  • 1
  • 1
Burt_Harris
  • 6,415
  • 2
  • 29
  • 64