我试图将cXML字符串反序列化为C#类。但是,在反序列化时,我似乎无法获得除反序列化之外的任何其他内容。 How to Deserialize XML document似乎提供了最大的帮助,并且使用该示例我已设法反序列化根cXML标记,但这不会对作为对象的嵌套对象PunchOutSetupRequest
起作用我真的需要反序列化。
在向您展示代码之前,我的问题是如何在不更改cXML.cs
文件的情况下将这些对象正确地反序列化为下面定义的cXML类?由于这是一个标准,我不想编辑它,除非我绝对不得不这样做。我的代码是公平的游戏。提前感谢您提供任何帮助,因为我知道这个主题涵盖了各个方面。
我有这个用于cXML的XSD文件,我已经使用xsd.exe
工具转换为C#类。我不会在这里粘贴整个架构以避免稀释问题,但如果您需要更完整的图片,可以转到cxml.org。
我的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
反序列化的代码。尽管我将xRoot
元素设置为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
生成的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;
}
}
}
答案 0 :(得分:1)
TL; DR; 我在将xsd文件转换为c#模型之前对其进行了解决。
在从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 Studio的[XML]-> [创建架构],Visual Studio将生成带有目标命名空间http://tempuri.org/cXML
的XSD。
如果在不删除这些名称空间引用的情况下(使用xsd2code或Visual Studio的xsd blah.xsd /classes
)从该XSD生成C#模型,则XmlSerializer会希望该名称空间用于要反序列化的XML中。
诸如SAP Ariba之类的平台不使用该tempuri.org命名空间。 XML节点将因此被跳过,因为如果没有名称空间引用,则无法识别这些节点。我发现这是因为触发了XmlSerializer.UnknownNode事件,告诉我它无法识别Header和Request之类的节点,并且它期望具有tempuri.org命名空间前缀的节点。
因此,如果您首先从XSD中删除伪造的名称空间,然后生成类(为此,我使用xsd2code),那么您将获得有效的c#(可反序列化)模型。
然后,您也不需要使用xRoot.ElementName = "cXML";
。它将从c#类中拾取根节点,因为它没有在tempuri.org命名空间中寻找<cXML>
标签。
因此,您无需“破坏”从XSD生成的类,就可以按原样使用它们。