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:

using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System.Dynamic;
using System.Xml.Linq;

This little helper function:

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);
}

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:

<?xml version="1.0" encoding="utf-8"?>
<Node1 Attribute1="test" Attribute2="another test">
  <SubNode1 SomeMoreAttributes="again" />
  <SubNode2>
    Some element text
  </SubNode2>
</Node1>
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;

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