XML parsing using XElement

joelc picture joelc · Feb 1, 2012 · Viewed 32.5k times · Source

Can't seem to find how to appropriately parse this using XElement:

<messages>
  <message subclass="a" context="d" key="g">
  <message subclass="b" context="e" key="h">
  <message subclass="c" context="f" key="i">
</messages>

I'd like to get this out to a List where is three strings subclass, context, key.

Answer

Anthony Pegram picture Anthony Pegram · Feb 1, 2012

Your input is not valid XML, it's missing closing tags on the inner message elements. But assuming the format was valid, you could parse out your structure as in:

string xml = @"<messages> 
                  <message subclass=""a"" context=""d"" key=""g""/> 
                  <message subclass=""b"" context=""e"" key=""h""/> 
                  <message subclass=""c"" context=""f"" key=""i""/> 
               </messages>";

var messagesElement = XElement.Parse(xml);
var messagesList = (from message in messagesElement.Elements("message")
                   select new 
                    {
                        Subclass = message.Attribute("subclass").Value,
                        Context = message.Attribute("context").Value,
                        Key = message.Attribute("key").Value
                    }).ToList();

You can also use XDocument for a full XML document, and use the Load method instead of Parse if you were using an XML file or a stream, for example. Additionally, you can select into a concrete class if you have one defined. Given a class definition of

class Message 
{
    public string Subclass { get; set; }
    public string Context { get; set; } 
    public string Key { get; set; }
}

You could use select new Message in the query, and the result would be a List<Message>, whereas right now it is a list of an anonymous type.