我正在尝试将cXML字符串反序列化为C#类。然而,在反序列化时,除了根元素之外,我似乎无法得到任何东西来反序列化。如何反序列化XML文档似乎提供了最多的帮助,使用该示例,我成功地反序列化了根cXML标记,但这并不适用于嵌套对象PunchOutSetupRequest,这是我真正需要反序列化的对象。
在向您展示代码墙之前,我的问题是,在不更改cXML文件的情况下,如何正确地将这些对象反序列化为下面定义的cXML.cs类?由于这是一个标准,我宁愿不编辑它,除非我绝对需要。我的代码是公平的。谢谢你的帮助,因为我知道这个话题涵盖的范围很广。
我为cXML提供了这个XSD文件,我已经使用xsd.exe工具将其转换为C#类。为了避免稀释问题,我不会在这里粘贴整个模式,但是如果需要更完整的图片,可以转到cxml.org。
My for cXML,它只是反序列化属性,不包含在cXML中定义的标头或请求对象:
using (TextReader reader = new StringReader(text))
{
try
{
XmlRootAttribute xRoot = new XmlRootAttribute();
xRoot.ElementName = "cXML";
xRoot.IsNullable = true;
var serializer = new XmlSerializer(typeof(cXML), xRoot);
cxml = (cXML)serializer.Deserialize(reader);
}
catch (Exception ex)
{
string r = "";
}
}尽管我将PunchOutSetupRequest deserialization.元素设置为PunchOutSetupRequest,但当它将cXML视为根节点时,它会抛出一个错误。
using (TextReader reader = new StringReader(text))
{
try
{
XmlRootAttribute xRoot = new XmlRootAttribute();
xRoot.ElementName = "PunchOutSetupRequest";
xRoot.IsNullable = true;
var serializer = new XmlSerializer(typeof(PunchOutSetupRequest), xRoot);
PunchOutSetupRequest request;
request = (PunchOutSetupRequest)serializer.Deserialize(reader);
}
catch (Exception ex)
{
string r = "";
}
}文本变量值(数据编辑):
<?xml version = '1.0' encoding = 'UTF-8'?>
<!DOCTYPE cXML SYSTEM "http://xml.cxml.org/schemas/cXML/1.1.007/cXML.dtd">
<cXML version="1.1.007" xml:lang="en-US" payloadID="" timestamp="2016-01- 04T03:21:32-05:00">
<Header>
<From>
<Credential domain="">
<Identity></Identity>
</Credential>
</From>
<To>
<Credential domain="">
<Identity></Identity>
</Credential>
</To>
<Sender>
<Credential domain="">
<Identity></Identity>
<SharedSecret></SharedSecret>
</Credential>
<UserAgent></UserAgent>
</Sender>
</Header>
<Request>
<PunchOutSetupRequest operation="create">
<BuyerCookie></BuyerCookie>
<Extrinsic name="User"></Extrinsic>
<BrowserFormPost>
<URL></URL>
</BrowserFormPost>
<Contact>
<Name xml:lang="en-US"></Name>
<Email></Email>
</Contact>
<SupplierSetup>
<URL></URL>
</SupplierSetup>
</PunchOutSetupRequest>
</Request>
</cXML>由xsd.exe (fragmented)生成的cXML类
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://tempuri.org/cXML")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://tempuri.org/cXML", IsNullable = false)]
public partial class cXML
{
private object[] itemsField;
private string versionField;
private string payloadIDField;
private string timestampField;
private string langField;
public cXML()
{
this.versionField = "1.1.010";
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("Header", typeof(Header))]
[System.Xml.Serialization.XmlElementAttribute("Message", typeof(Message))]
[System.Xml.Serialization.XmlElementAttribute("Request", typeof(Request))]
[System.Xml.Serialization.XmlElementAttribute("Response", typeof(Response))]
public object[] Items
{
get
{
return this.itemsField;
}
set
{
this.itemsField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
[System.ComponentModel.DefaultValueAttribute("1.1.010")]
public string version
{
get
{
return this.versionField;
}
set
{
this.versionField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string payloadID
{
get
{
return this.payloadIDField;
}
set
{
this.payloadIDField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string timestamp
{
get
{
return this.timestampField;
}
set
{
this.timestampField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified, Namespace = "http://www.w3.org/XML/1998/namespace")]
public string lang
{
get
{
return this.langField;
}
set
{
this.langField = value;
}
}
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://tempuri.org/cXML")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://tempuri.org/cXML", IsNullable = false)]
public partial class PunchOutSetupRequest
{
private BuyerCookie buyerCookieField;
private Extrinsic[] extrinsicField;
private BrowserFormPost browserFormPostField;
private Contact[] contactField;
private SupplierSetup supplierSetupField;
private ShipTo shipToField;
private SelectedItem selectedItemField;
private ItemOut[] itemOutField;
private PunchOutSetupRequestOperation operationField;
/// <remarks/>
public BuyerCookie BuyerCookie
{
get
{
return this.buyerCookieField;
}
set
{
this.buyerCookieField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("Extrinsic")]
public Extrinsic[] Extrinsic
{
get
{
return this.extrinsicField;
}
set
{
this.extrinsicField = value;
}
}
/// <remarks/>
public BrowserFormPost BrowserFormPost
{
get
{
return this.browserFormPostField;
}
set
{
this.browserFormPostField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("Contact")]
public Contact[] Contact
{
get
{
return this.contactField;
}
set
{
this.contactField = value;
}
}
/// <remarks/>
public SupplierSetup SupplierSetup
{
get
{
return this.supplierSetupField;
}
set
{
this.supplierSetupField = value;
}
}
/// <remarks/>
public ShipTo ShipTo
{
get
{
return this.shipToField;
}
set
{
this.shipToField = value;
}
}
/// <remarks/>
public SelectedItem SelectedItem
{
get
{
return this.selectedItemField;
}
set
{
this.selectedItemField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("ItemOut")]
public ItemOut[] ItemOut
{
get
{
return this.itemOutField;
}
set
{
this.itemOutField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public PunchOutSetupRequestOperation operation
{
get
{
return this.operationField;
}
set
{
this.operationField = value;
}
}
}发布于 2020-05-21 11:27:56
TL;DR;我解决了这个问题,在将它转换为c#模型之前编辑了xsd文件。
在从DTD生成的XSD中,更改:
<xs:schema xmlns="http://tempuri.org/cXML" xmlns:ds="uri:ds" elementFormDefault="qualified" targetNamespace="http://tempuri.org/cXML" xmlns:xs="http://www.w3.org/2001/XMLSchema">
至:
<xs:schema xmlns:ds="uri:ds" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
更长的解释:
如果在DTD文件上使用Visual的XML->Create,visual将生成一个具有目标命名空间http://tempuri.org/cXML的XSD。
如果您在不删除这些名称空间引用的情况下从XSD生成C#模型(使用xsd2code或visual的xsd blah.xsd /classes),那么XmlSerializer将期望在您想要反序列化的XML中使用该名称空间。
SAP等平台不使用该tempuri.org命名空间。因此,XML节点将被跳过,因为如果没有命名空间引用,就无法识别这些节点。我发现这是因为XmlSerializer.UnknownNode事件触发了,告诉我它不识别节点,比如头节点和请求节点,并且它希望节点具有tempuri.org名称空间前缀。
因此,如果您首先从XSD中删除伪命名空间,然后生成类(我为此使用了xsd2code ),那么您将得到有效的c# (De)可序列化模型。
然后,您也不需要使用xRoot.ElementName = "cXML";。它将从c#类中获取根节点,因为它不查找带有tempuri.org命名空间的<cXML>标记。
因此,这样您不需要“分解”从XSD生成的类,您可以按原样使用它们。
https://stackoverflow.com/questions/34620074
复制相似问题