How to use Complex types with xs:any / ##any and mixed in code generated by the XSD tool

3.7k Views Asked by At

I have the following complex type in my XML schema:

<xs:complexType name="Widget" mixed="true">
    <xs:sequence>
        <xs:any namespace="##any" processContents="skip" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
</xs:complexType>

The element in derived XML could contain string or could contained wellformed XML, hence the mixed attribute being true.

When I run this through the .NET XSD Tool I get the following generate code:

public partial class Widget{

    private System.Xml.XmlNode[] anyField;

    /// <remarks/>
    [System.Xml.Serialization.XmlTextAttribute()]
    [System.Xml.Serialization.XmlAnyElementAttribute()]
    public System.Xml.XmlNode[] Any {
        get {
            return this.anyField;
        }
        set {
            this.anyField = value;
        }
    }
}

The question I have is that I am not entirely sure how I should then use this. Ultimately I need to be able to set the value of widget to either:

<widget>Hello World!</widget>

or

<widget>
  <foo>Hello World</foo>
</widget>

Both of which validate agaisnt the schema

2

There are 2 best solutions below

4
On BEST ANSWER

For this:

<widget>  
    <foo>Hello World</foo>
</widget>

Use this:

XmlDocument dom = new XmlDocument();
Widget xmlWidget = new Widget();
xmlWidget.Any = new XmlNode[1];
xmlWidget.Any[0] = dom.CreateNode(XmlNodeType.Element, "foo", dom.NamespaceURI);
xmlWidget.Any[0].InnerText = "Hello World!";

For this:

<widget>Hello World!</widget>

Use this:

XmlDocument dom = new XmlDocument();
XmlNode node = dom.CreateNode(XmlNodeType.Element, "foo", dom.NamespaceURI);
node.InnerText = "Hello World";

Widget w = new Widget();
w.Any = new XmlNode[1];
w.Any[0] = node.FirstChild; 
3
On

Posting this as a answer as technically it works and answers the question. However it seems like a really nasty hack. So if anybody has an alternative and better solution I am all ears.

string mystring= "if I check this code in it will at least have comedy value";

XmlDocument thisLooksBad = new XmlDocument();
thisLooksBad.LoadXml("<temp>" + mystring + "</temp>");

Widget stringWidget = new Widget();
stringWidget.Any = new XmlNode[1];
stringWidget.Any[0] = thisLooksBad.SelectSingleNode("/temp").FirstChild;

As you can see I am placing my string into an XmlDocument wrapped in tags, this works, compiles and serializes without issues - so yes it is a solution but it strikes me that this is a nasty hack.

string myxml = "<x><y>something</y></x>";

XmlDocument thisDoesntLookSoBad = new XmlDocument();
thisLooksBad.LoadXml(myxml);

Widget xmlWidget = new Widget();
xmlWidget.Any = new XmlNode[1];
xmlWidget.Any[0] = thisDoesntLookSoBad;

In this example I am placing my XML into an XmlDocument and then assigning that to the generated class. This makes more sense as I am working with XML not raw string.

Curiously I can also do this and it works as well (but is also a nasty hack):

string myxml = "<x><y>something</y></x>";

XmlDocument dom = new XmlDocument();
dom.LoadXml("<temp>" + myxml + "</temp>");

Widget xmlWidget = new Widget();
xmlWidget.Any = new XmlNode[1];
xmlWidget.Any[0] = dom.SelectSingleNode("/temp").FirstChild;