Paddy
Paddy

Reputation: 33857

c# serialization - complex type containing simple content with attributes

I have an existing solution that has used svcutil to create a set of classes based on an XSD schema. I am now having to make edits to that schema and I have run into a bit of a stumbling block.

The schema is going to be extended with types like this:

<xsd:complexType name="Awkward">
  <xsd:sequence>
    <xsd:element name="awkward1" type="tt:AwkwardChild" nillable="true">      
    </xsd:element>
    <xsd:element name="awkward2" type="tt:AwkwardChild" nillable="true">
    </xsd:element>
  </xsd:sequence>
</xsd:complexType>

<xsd:complexType name="AwkwardChild">
  <xsd:simpleContent>
    <xsd:extension base="tt:AwkwardChildType">
      <xsd:attribute name="id" type="xsd:ID"/>
    </xsd:extension>
  </xsd:simpleContent>
</xsd:complexType>

<xsd:simpleType name="AwkwardChildType">
  <xsd:restriction base="xsd:string">
    <xsd:enumeration value="Dependent"/>
    <xsd:enumeration value="In between"/>
    <xsd:enumeration value="Independent"/>
  </xsd:restriction>
</xsd:simpleType>

Which would result in XML output something like this:

<Awkward>
  <awkward1 id="z1">Dependent</awkward1>
  <awkward2 id="z2">Independent</awkward2>
</Awkward>

SVCUtil is choking when trying to generate this complaining that

"Type 'AwkwardChild' in namespace tt cannot be imported. Complex types with simple content extension are not supported. Either change the schema so that the types can map to data contract types or use ImporXmlType or use a different serializer."

And I think that I understand this, as it is trying to output a string type, but include attributes with it.

I am trying to figure out if there is a way I can hand code a class to achieve this kind of output, but I can't figure out a way to get the string to appear as 'simple content' in the xml node rather than as a child element, e.g. this class:

[DataContractAttribute(Name = "AwkwardChild", Namespace = "tt")]
    public class Awkward
    {
        [DataContractAttribute(Name="id")]
        public string id { get; set; }

        //What do I put here to get this to appear as the content of 
        //the awkward node, not in an element?
        public string nodecontent { get; set; }
    }

Could somebody point me in the right direction?

Upvotes: 3

Views: 1242

Answers (2)

JasonJ387
JasonJ387

Reputation: 1

I know it's a bit late, but thought you might like to know.

[XmlType(TypeName = "AwkwardChild")]
public sealed class AwkwardChild
{
    [XmlText()]
    public String Value { get; set; }

    [XmlAttribute(AttributeName = "id")]
    public String Id { get; set; }
}

Upvotes: 0

Paddy
Paddy

Reputation: 33857

This could not be worked around using the SVCUtil tool and the XMLSerializer option. In the end, I had to hand code a class for this particular section that implemented IXmlSerializable and outputted the appropriate XML in the write XML method. Small sample snippet below.

writer.WriteStartElement("awkward1");

writer.WriteAttributeString("id1", "z1");

writer.WriteValue(nodeValue);

writer.WriteEndElement();

Upvotes: 1

Related Questions