我正在努力为这个xml创建反序列化类:
<?xml version="1.0" encoding="ISO-8859-1"?>
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:stn="urn:response">
<SOAP-ENV:Body>
<Response>
<Records xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="stn:Record[1]">
<item xsi:type="stn:Record">
<person xsi:type="xsd:string">John Johnos</person>
<address xsi:type="xsd:string">Some Street 1</address>
<age xsi:type="xsd:string">24</age>
</item>
</Records>
<status xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="stn:status[1]">
<item xsi:type="stn:status">
<status xsi:type="xsd:string">success</status>
<message xsi:type="xsd:string"/>
</item>
</status>
</Response>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
我尝试使用自动创建的代码(在VisualStudio 12中:编辑 - &gt;选择性粘贴 - >将XML粘贴为类):
/// <remarks/>
[System.SerializableAttribute()]
[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 EnvelopeBody bodyField;
private string encodingStyleField;
/// <remarks/>
public EnvelopeBody Body
{
get
{
return this.bodyField;
}
set
{
this.bodyField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified)]
public string encodingStyle
{
get
{
return this.encodingStyleField;
}
set
{
this.encodingStyleField = value;
}
}
}
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public partial class EnvelopeBody
{
private Response responseField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Namespace = "")]
public Response Response
{
get
{
return this.responseField;
}
set
{
this.responseField = value;
}
}
}
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class Response
{
private ResponseRecords recordsField;
private ResponseStatus statusField;
/// <remarks/>
public ResponseRecords Records
{
get
{
return this.recordsField;
}
set
{
this.recordsField = value;
}
}
/// <remarks/>
public ResponseStatus status
{
get
{
return this.statusField;
}
set
{
this.statusField = value;
}
}
}
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class ResponseRecords
{
private ResponseRecordsItem itemField;
private string arrayTypeField;
/// <remarks/>
public ResponseRecordsItem item
{
get
{
return this.itemField;
}
set
{
this.itemField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified, Namespace = "http://schemas.xmlsoap.org/soap/encoding/")]
public string arrayType
{
get
{
return this.arrayTypeField;
}
set
{
this.arrayTypeField = value;
}
}
}
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class ResponseRecordsItem
{
private string personField;
private string addressField;
private byte ageField;
/// <remarks/>
public string person
{
get
{
return this.personField;
}
set
{
this.personField = value;
}
}
/// <remarks/>
public string address
{
get
{
return this.addressField;
}
set
{
this.addressField = value;
}
}
/// <remarks/>
public byte age
{
get
{
return this.ageField;
}
set
{
this.ageField = value;
}
}
}
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class ResponseStatus
{
private ResponseStatusItem itemField;
private string arrayTypeField;
/// <remarks/>
public ResponseStatusItem item
{
get
{
return this.itemField;
}
set
{
this.itemField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified, Namespace = "http://schemas.xmlsoap.org/soap/encoding/")]
public string arrayType
{
get
{
return this.arrayTypeField;
}
set
{
this.arrayTypeField = value;
}
}
}
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class ResponseStatusItem
{
private string statusField;
private object messageField;
/// <remarks/>
public string status
{
get
{
return this.statusField;
}
set
{
this.statusField = value;
}
}
/// <remarks/>
public object message
{
get
{
return this.messageField;
}
set
{
this.messageField = value;
}
}
}
我试图在XMLSerializer的帮助下反序列化:
var serializer = new XmlSerializer(typeof(Envelope));
var reader = new StringReader(response);
var flResponse = (Envelope)serializer.Deserialize(reader);
我收到的错误消息:
Message=The specified type was not recognized: name='Array', namespace='http://schemas.xmlsoap.org/soap/encoding/', at <Records xmlns=''>.
你能帮我改一下这个xml的反序列化类吗?
答案 0 :(得分:6)
我尝试了很多东西并最终弄明白了。您发布的Xml无效,因为xsi:type不能用于反序列化。
有效的XML应如下所示:
<?xml version="1.0" encoding="ISO-8859-1"?>
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:stn="urn:response">
<SOAP-ENV:Body>
<Response>
<Records>
<item>
<person >John Johnos</person>
<address >Some Street 1</address>
<age >24</age>
</item>
</Records>
<status>
<item>
<status >success</status>
<message/>
</item>
</status>
</Response>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
代码应如下所示:
XDocument xml = XDocument.Parse(xmlInput);
XmlSerializer serializer = new XmlSerializer(typeof(Response));
using (StringReader stream = new StringReader(items[0].ToString()))
{
var output = (Response)serializer.Deserialize(stream);
}
Autogenerate类将来自:
<Response>
<Records xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<item>
<person>John Johnos</person>
<address >Some Street 1</address>
<age>24</age>
</item>
</Records>
<status xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<item >
<status >success</status>
<message />
</item>
</status>
</Response>
希望这很清楚。不知道如何从Envelope中删除类型,这可能不是你想要的解决方案。
我用来从Envelope获取东西的方法是XDocument.Descendants(elemmentName)
,它返回该名称的元素或List元素,然后你可以填充对象。它的工作量更大,但我认为它比转换xml更适合反序列化。
答案 1 :(得分:5)
为什么不为整个架构生成序列化库?
从邮件中的URL下载XSD架构文件并将其保存在某处
打开Visual Studio命令提示符并输入以下命令
xsd / classes SoapEncoding.xsd
输出将是一个标题为SoapEncoding.cs
。
如果一切顺利,这一切都应该有效。
答案 2 :(得分:0)
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.FileName = @"C:\Windows\system32\cmd.exe";
string anyCommand = "cd C:\\Users\\JR5053169\\Documents\\visual studio 2010\\Projects\\WindowsFormsApplication1\\WindowsFormsApplication1\\bin\\Debug xsd";
//C:\\Users\\JR5053169\\Documents\\visual studio 2010\\Projects\\WindowsFormsApplication1\\WindowsFormsApplication1
//C:\\Users\\JR5053169\\Documents\\visual studio 2010\\Projects\\WindowsFormsApplication1\\WindowsFormsApplication1\\bin\\Debug
startInfo.Arguments = "/c " + anyCommand;
process.StartInfo = startInfo;
process.Start();
string Command1 = "xsd MakePayment.xml";
startInfo.Arguments = "/c " + Command1;
process.StartInfo = startInfo;
process.Start();
string Command2 = "xsd /c MakePayment.xsd";
startInfo.Arguments = "/c " + Command2;
process.StartInfo = startInfo;
process.Start();