Quickly parsing XML in C#

Yesterday I had an interesting task. I needed to parse a collection of XML files in C# and wondered if there’s an easy way to just access the data without all the XPath/XML fuzz.

After some research I found a couple of approaches and I mixed and matched them to a pretty simple one using dynamic and the ExpandoObject:
You will need these namespaces:

[code language=”csharp”]
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System.Dynamic;
using System.Xml.Linq;
[/code]

This little helper function:

[code language=”csharp”]
public static dynamic ConvertXmlStringToDynamic(string
{
XDocument doc = XDocument.Parse(xmlData);
string jsonText = JsonConvert.SerializeXNode(doc);
jsonText = jsonText.Replace("\"@", "\"");
jsonText = jsonText.Replace("\"#text\"", "\"text\"");
var converter = new ExpandoObjectConverter();
return JsonConvert.DeserializeObject<ExpandoObject>(jsonText, converter);
}
[/code]

I first create an XDocument which then gets converted to a json string using JsonConvert.SerializeXNode. The json string will then be deserialized into an ExpandoObject. Very hacky but works great with two caveats: The two replace methods are kind of hacky because the resulting keys in the ExpandoObject for XML attributes are prefixed with an @ character and the key of an XML element content is #text. This makes it impossible to access using their property names. So I simply hacked it by replacing those in the json string before I convert it. This can be dangerous! Double-check if nothing else got replaced by this by mistake!

Once you got your dynamic, you can simply access the data from your XML like this:

[code language=”xml”]
<?xml version="1.0" encoding="utf-8"?>
<Node1 Attribute1="test" Attribute2="another test">
<SubNode1 SomeMoreAttributes="again" />
<SubNode2>
Some element text
</SubNode2>
</Node1>
[/code]

[code language=”csharp”]
var sampleFile = @"C:\some-file.xml";
var sampleXml = File.ReadAllText(sampleFile);
var data = Converter.ConvertXmlStringToDynamic(sampleXml);
var attribute1 = data.Node1.Attribute1;
var someMoreAttribute = data.Node1.SubNode1.SomeMoreAttributes;
var elementText = data.Node1.SubNode2.text;
[/code]

The above served me well. Maybe there’s a simpler or better solution and if so, I’m happy to hear about it!

Photo by Pankaj Patel on Unsplash

Leave a Reply