首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将cXML反序列化为C#类

将cXML反序列化为C#类
EN

Stack Overflow用户
提问于 2016-01-05 19:50:00
回答 1查看 2.2K关注 0票数 4

我正在尝试将cXML字符串反序列化为C#类。然而,在反序列化时,除了根元素之外,我似乎无法得到任何东西来反序列化。如何反序列化XML文档似乎提供了最多的帮助,使用该示例,我成功地反序列化了根cXML标记,但这并不适用于嵌套对象PunchOutSetupRequest,这是我真正需要反序列化的对象。

在向您展示代码墙之前,我的问题是,在不更改cXML文件的情况下,如何正确地将这些对象反序列化为下面定义的cXML.cs类?由于这是一个标准,我宁愿不编辑它,除非我绝对需要。我的代码是公平的。谢谢你的帮助,因为我知道这个话题涵盖的范围很广。

我为cXML提供了这个XSD文件,我已经使用xsd.exe工具将其转换为C#类。为了避免稀释问题,我不会在这里粘贴整个模式,但是如果需要更完整的图片,可以转到cxml.org

My for cXML,它只是反序列化属性,不包含在cXML中定义的标头或请求对象:

代码语言:javascript
复制
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视为根节点时,它会抛出一个错误。

代码语言:javascript
复制
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 = "";
                }
            }

文本变量值(数据编辑):

代码语言:javascript
复制
<?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类

代码语言:javascript
复制
[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;
    }
}
}
EN

回答 1

Stack Overflow用户

发布于 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生成的类,您可以按原样使用它们。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34620074

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档