Search code examples
xmlxsdschema

How can I configure my XSD schema to generate xmlns attributes on nested elements?


I created this XSD file and named it Envelope.xsd...

<w3:schema xmlns:w3="http://www.w3.org/2001/XMLSchema">
  <w3:element name="Envelope">
    <w3:complexType>
      <w3:sequence>
        <w3:element name="Unit">
          <w3:complexType>
            <w3:sequence>
              <w3:element name="EncryptedData">
                <w3:complexType>
                  <w3:sequence>
                    <w3:element name="KeyInfo">
                      <w3:complexType>
                        <w3:sequence>
                          <w3:element name="KeyName" type="w3:string" />
                        </w3:sequence>
                      </w3:complexType>
                    </w3:element>
                  </w3:sequence>
                </w3:complexType>
              </w3:element>
            </w3:sequence>
          </w3:complexType>
        </w3:element>
      </w3:sequence>
    </w3:complexType>
  </w3:element>
</w3:schema>

Then, I used this command on it with xsd.exe (comes with Visual Studio) to produce my C# code file...

xsd.exe /c Envelope.xsd

Then, in my code I created a new Envelope object named MyEnvelope and serialized it using this code...

var serializer = new XmlSerializer(typeof(Envelope));
var namespaces = new XmlSerializerNamespaces();
namespaces.Add("", "");
var writer = new StringWriter();
serializer.Serialize(writer, MyEnvelope, namespaces);
var MyEnvelopeSerialized = writer.ToString();

This is what the resulting serialzed Envelope (i.e. MyEnvelopeSerialized) looked like...

<Envelope>
  <Unit>
    <EncryptedData>
      <KeyInfo>
        <KeyName>MyValue</KeyName>
      </KeyInfo>
    </EncryptedData>
  </Unit>
</Envelope>

And now for the important part. Instead, I must make the output look exactly like this...

<Envelope>
  <Unit>
    <EncryptedData xmlns="http://www.w3.org/2001/04/xmlenc#">
      <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
        <KeyName>MyValue</KeyName>
      </KeyInfo>
    </EncryptedData>
  </Unit>
</Envelope>

How can I modify the Envelope.xsd file so that, when xsd.exe parses it and generates the C# code file, XmlSerializer will then add the "xmlns..." attributes to the <EncryptedData> and <KeyInfo> tags?


Solution

  • Please try the following XSD.

    XSD

    <?xml version="1.0" encoding="UTF-8"?>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" xmlns:xmldsig="http://www.w3.org/2000/09/xmldsig#" xmlns:xmlenc="http://www.w3.org/2001/04/xmlenc#">
      <xs:import namespace="http://www.w3.org/2000/09/xmldsig#" schemaLocation="xmldsig.xsd"/>
      <xs:import namespace="http://www.w3.org/2001/04/xmlenc#" schemaLocation="xmlenc.xsd"/>
      <xs:element name="Envelope">
        <xs:complexType>
          <xs:sequence>
            <xs:element ref="Unit"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
      <xs:element name="Unit">
        <xs:complexType>
          <xs:sequence>
            <xs:element ref="xmlenc:EncryptedData"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:schema>