简体   繁体   中英

How to parse an arbitrary XML string into a structured object

I have a string of XML data whose schema is unknown. I would like to parse it into a tree structure my code can easily peruse. For example if the string is:

<foo><bar>baz</bar></foo>

I want to be able to access it with code like:

elem["foo"]["bar"]

and get baz .

EDIT: The supposed "duplicate" assumes you do know the structure / schema of the XML. As I originally stated, I do not

It sounds pretty much like you want what LINQ to XML offers. Parse XML like so:

var doc = XDocument.Parse(@"<foo><bar>baz</bar></foo>");

Then you could query it in a similar way to your suggested syntax:

var barValue = (string)doc.Elements("foo").Elements("bar").Single()

or:

var barValue = (string)doc.Descendants("bar").Single()

See the docs for more info.

Personally, I agree with the other answers that a LINQ to XML based solution is best. Something like:

string xml = "<root><foo><bar>baz</bar></foo></root>";
string s = XElement.Parse(xml).Element("foo").Element("bar").Value;

But if you really wanted behaviour like your example, you could write a small wrapper class such as:

EDIT: Example updated to be indexable using a multidimensional indexer note .

class MyXmlWrapper
{
    XElement _xml;

    public MyXmlWrapper(XElement xml)
    {
        _xml = xml;
    }

    public MyXmlWrapper this[string name, int index = 0]
    {
        get
        {
            return new MyXmlWrapper(_xml.Elements(name).ElementAt(index));
        }
    }

    public static implicit operator string(MyXmlWrapper xml)
    {
        return xml._xml.Value;
    }
}

And use that exactly like you wanted:

string xml = "<root><foo><bar>baz</bar></foo></root>";
MyXmlWrapper wrapper = new MyXmlWrapper(XElement.Parse(xml));
string s = wrapper["foo"]["bar"];

Edited example for returning an element from a collection:

string xml = "<root><foo><bar><baz>1</baz><baz>2</baz></bar></foo></root>";
MyXmlWrapper wrapper = new MyXmlWrapper(XElement.Parse(xml));
string baz1 = wrapper["foo"]["bar"]["baz", 0];
string baz2 = wrapper["foo"]["bar"]["baz", 1];

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM