简体   繁体   中英

How to define and serialize c# object(s) to generate specific xml?

I want write C# classes, so that when I am serialize them in to XML, it should generate the following XML schema.

    <soapenv:Envelope
            xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
            xmlns:web="http://webservice.api.cabaret.com/"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns:xs="http://www.w3.org/2001/XMLSchema">
   <soapenv:Header/>
   <soapenv:Body>
      <web:callArgs>
         <name></name>
         <args>
            <entries>
               <name>locator.content</name>
               <value xsi:type="xs:string">AA==</value>
            </entries>
            <entries>
               <name>locator.name</name>
               <value xsi:type="xs:string">Reha0850.pdf</value>
            </entries>
         </args>
      </web:callArgs>
   </soapenv:Body>
</soapenv:Envelope>

Please provide me the help, how should i write the c# classes and serialize them to generate above mentioned XML schema.

In general, if you want to create c# classes from XML automatically, you can follow the instructions from Generate C# class from XML or Convert XML String to Object , then use XmlSerializer .

From the XML provided and following the instructions from the first answer, I created classes using xsd.exe at the command prompt:

prompt> rem Create XSD files
prompt> xsd SoapEnvelope.xml
prompt> rem convert to c# classes
prompt> rem root class is Envelope, in namespace Question35933150 
prompt> xsd SoapEnvelope.xsd SoapEnvelope_app1.xsd /classes /namespace:Question35933150 /e:Envelope

Then I added the included classes to Visual Studio and built -- and found one problem. xsd.exe inferred the value property should be of type string rather than a polymorphic type with a possible type of string . The property needs to be polymorphic in order for the serialized to add the xsi:type="xs:string" attribute. See Xsi:type Attribute Binding Support and Controlling XML Serialization Using Attributes: Serializing Derived Classes .

Thus I had to fix the generated class manually by changing the value property to be of type object and adding [XmlInclude(typeof(string))] :

[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://webservice.api.cabaret.com/")]
[XmlInclude(typeof(string))] // Manually added
public partial class callArgsEntries
{
    private string nameField;

    private object valueField; // Manually changed to object

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public string name
    {
        get
        {
            return this.nameField;
        }
        set
        {
            this.nameField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public object value // Manually changed to object
    {
        get
        {
            return this.valueField;
        }
        set
        {
            this.valueField = value;
        }
    }
}

The remaining auto-generated classes I left as-is:

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://schemas.xmlsoap.org/soap/envelope/", IsNullable = false)]
public partial class Envelope
{

    private string headerField;

    private EnvelopeBody[] bodyField;

    /// <remarks/>
    public string Header
    {
        get
        {
            return this.headerField;
        }
        set
        {
            this.headerField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("Body")]
    public EnvelopeBody[] Body
    {
        get
        {
            return this.bodyField;
        }
        set
        {
            this.bodyField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public partial class EnvelopeBody
{

    private callArgs callArgsField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Namespace = "http://webservice.api.cabaret.com/")]
    public callArgs callArgs
    {
        get
        {
            return this.callArgsField;
        }
        set
        {
            this.callArgsField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://webservice.api.cabaret.com/")]
public partial class callArgs
{

    private string nameField;

    private callArgsEntries[] argsField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public string name
    {
        get
        {
            return this.nameField;
        }
        set
        {
            this.nameField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlArrayAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
    [System.Xml.Serialization.XmlArrayItemAttribute("entries", Form = System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable = false)]
    public callArgsEntries[] args
    {
        get
        {
            return this.argsField;
        }
        set
        {
            this.argsField = value;
        }
    }
}

Deserializing your XML and reserializing using these classes with XmlSerializer produces the following XML, which has the schema you require:

<Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/soap/envelope/">
    <Header />
    <Body>
        <callArgs xmlns="http://webservice.api.cabaret.com/">
            <name xmlns="" />
            <args xmlns="">
                <entries>
                    <name>locator.content</name>
                    <value xsi:type="xsd:string">AA==</value>
                </entries>
                <entries>
                    <name>locator.name</name>
                    <value xsi:type="xsd:string">Reha0850.pdf</value>
                </entries>
            </args>
        </callArgs>
    </Body>
</Envelope>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM