Skip to content

Instantly share code, notes, and snippets.

@rgl
Created March 22, 2012 14:41
Show Gist options
  • Save rgl/2158698 to your computer and use it in GitHub Desktop.
Save rgl/2158698 to your computer and use it in GitHub Desktop.
Serialize xsd:anyType on a client proxy
/*
When you have a XML schema with a xsd:anyType element, eg:
<complexType name="Example">
<sequence>
<element name="DateTime" type="dateTime" minOccurs="1" maxOccurs="1" />
<element name="Value" type="string" minOccurs="1" maxOccurs="1" />
<element name="Details" type="anyType" minOccurs="0" maxOccurs="1" />
</sequence>
</complexType>
And generate a service proxy, you'll get a class with something alike:
...
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://example.com")]
public partial class Example: object, System.ComponentModel.INotifyPropertyChanged
{
[System.Xml.Serialization.XmlElementAttribute(Order=0)]
public System.DateTime DateTime { get; set; }
[System.Xml.Serialization.XmlElementAttribute(Order=1)]
public string Value { get; set; }
[System.Xml.Serialization.XmlElementAttribute(Order=2)]
public object Details { get; set; }
}
Notice that the Details property type is-a object. How will we set this property value?
In my particular case, I want to set it to an arbitrary XML fragment; it turns out we
have to manually fiddle with the generated code by doing the following:
1. create a new class to represent the Details, eg: ExampleDetails.
2. change the Example.Details property type, eg: to ExampleDetails.
In this gist I'll show the ExampleDetails class.
*/
...
using System.Runtime.Serialization;
using System.Xml;
using System.Xml.Serialization;
public class ExampleDetails : IXmlSerializable
{
private readonly XmlNode[] _details;
public MetricDetails()
{
}
public MetricDetails(XmlNode[] details)
{
_details = details;
}
public XmlSchema GetSchema()
{
return null;
}
public void ReadXml(XmlReader reader)
{
throw new NotImplementedException();
}
public void WriteXml(XmlWriter writer)
{
XmlSerializableServices.WriteNodes(writer, _details);
}
}
//
// Create ExampleDetails with something like:
private static ExampleDetails CreateExampleDetails(IEnumerable<XElement> elements)
{
var doc = new XmlDocument();
var details = elements.Select(element =>
{
var node = doc.CreateElement(element.Name.LocalName);
node.AppendChild(doc.CreateTextNode(element.Value));
return node;
}
).ToArray();
return new ExampleDetails(details);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment