-1

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

9
  • 1
    Possible duplicate of How to Deserialize XML document Commented Jan 6, 2016 at 17:10
  • 1
    Not a duplicate - this is about accessing a parsed XML object, not to deserialize into a (strongly typed) class. Commented Jan 6, 2016 at 17:25
  • @Donal you can't really deserialize XML to objects if the schema is unknown. Commented Jan 6, 2016 at 17:25
  • @CharlesMager, see answer... apparently you can Commented Jan 6, 2016 at 17:26
  • 1
    Of course, there is a duplicate: stackoverflow.com/questions/55828/how-does-one-parse-xml-files Commented Jan 6, 2016 at 17:26

3 Answers 3

3

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.

Sign up to request clarification or add additional context in comments.

Comments

2

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 indexernote.

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];

3 Comments

The OP has clarified that he wants to parse arbitrary XML files.
@LeonardoHerrera this does parse arbitrary XML files?
Not really - we don't know what kind of XML we'll get. For example, you can't get the second baz element in <root><foo><bar><baz>1</baz><baz>2</baz></bar></foo></root>.
1

XDocument.Parse(string) is your friend:

https://msdn.microsoft.com/en-us/library/bb345532(v=vs.110).aspx

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.