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>