2

I'm wondering if there is a built-in or open-source implementation of DynamicXml?

Something like

var djson = System.Web.Helpers.Json.Decode(jsonText);
int id = djson.Id;

but for xml strings.

So rather than write

xitem.Element("SomeElement")

I'd like to have

dxitem.SomeElement
John Saunders
  • 160,644
  • 26
  • 247
  • 397
Scott Weinstein
  • 18,890
  • 14
  • 78
  • 115

3 Answers3

1

Jon Skeet's C# In Depth talks about this idea in Chapter 14 (the chapter on dynamic bahviour in C# 4), and there's downloadable source here.

Community
  • 1
  • 1
AakashM
  • 62,551
  • 17
  • 151
  • 186
0

Recently I spent some time building dynamic wrapper around XElement and XDocument for one of my projects, you can take a look at it here.

Idea exactly the same but I split implementation into two separate classes: DynamicXmlReader and DynamicXmlWriter, where former could only read elements and attributes and later could add subelements and attributes. And DynamicXmlReader throws an exception if it could not find appropriate sub element or attribute but DynamicXmlWriter adds them into underlying XElement.

For example, here two of my unit tests where I'm using sample from Jon Skeet's book:

[TestCase]
public void SkeetBookXmlTest()
{
string books =
@"<books>
  <book name=""Mortal Engines"">
    <author name=""Philip Reeve"" />
  </book>
  <book name=""The Talisman"">
    <author name=""Stephen King"" />
    <author name=""Peter Straub"" />
  </book>
  <book name=""Rose"">
    <author name=""Holly Webb"" />
    <excerpt>Rose was remembering the illustrations from Morally Instructive Tales for the Nursery.</excerpt>
  </book>
</books>";
    dynamic dynamicXml = XElement.Parse(books).AsDynamic();

    Assert.That(dynamicXml.book[0]["name"].Value, Is.EqualTo("Mortal Engines"));

    Assert.That(dynamicXml.book[0].author["name"].Value, Is.EqualTo("Philip Reeve"));

    Assert.That(dynamicXml.book[2]["name"].Value, Is.EqualTo("Rose"));

    Assert.That((string)dynamicXml.book[2].excerpt, Is.EqualTo("Rose was remembering the illustrations from Morally Instructive Tales for the Nursery."));

}

Or another unit test that creates exactly the same xml document:

[TestCase]
public void SkeetBookXmlTest()
{
    // Jon Skeet in his C# in Depth used following sample
    string books =
@"<books>
  <book name=""Mortal Engines"">
    <author name=""Philip Reeve"" />
  </book>
  <book name=""The Talisman"">
    <author name=""Stephen King"" />
    <author name=""Peter Straub"" />
  </book>
  <book name=""Rose"">
    <author name=""Holly Webb"" />
    <excerpt>Rose was remembering the illustrations from Morally Instructive Tales for the Nursery.</excerpt>
  </book>
</books>";

// Lets create this data dynamically
XElement element = new XElement("books");
dynamic dynamicXml = element.AsDynamicWriter();

dynamicXml.book[0]["name"] = "Mortal Engines";
dynamicXml.book[0].author["name"] = "Philip Reeve";

dynamicXml.book[1]["name"] = "The Tailisman";
dynamicXml.book[1].author[0]["name"] = "Stephen King";
dynamicXml.book[1].author[1]["name"] = "Peter Straub";

dynamicXml.book[2]["name"] = "Rose";
dynamicXml.book[2].author["name"] = "Holly Webb";
dynamicXml.book[2].excerpt = "Rose was remembering the illustrations from Morally Instructive Tales for the Nursery.";

Console.WriteLine(element);

Assert.That(dynamicXml.book[0]["name"].Value, Is.EqualTo("Mortal Engines"));

Assert.That(dynamicXml.book[0].author["name"].Value, Is.EqualTo("Philip Reeve"));

Assert.That(dynamicXml.book[2]["name"].Value, Is.EqualTo("Rose"));

Assert.That((string)dynamicXml.book[2].excerpt, Is.EqualTo("Rose was remembering the illustrations from Morally Instructive Tales for the Nursery."));

}
Sergey Teplyakov
  • 11,477
  • 34
  • 49