【问题标题】:XSD not generating C# class as I expectXSD 没有像我预期的那样生成 C# 类
【发布时间】:2011-05-18 16:05:23
【问题描述】:

我有以下 xml 文件:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
  <SOAP-ENV:Header xmlns:hdr="http://xml.example.com/ns/appmw/soap/1.0/header">
    <hdr:FinalMessage>true</hdr:FinalMessage>
  </SOAP-ENV:Header>
  <SOAP-ENV:Body>
    <MyResponse>
      <Result seqNo="0">
        <MetaData>
          <DataSchema>
            <ColumnSchema type="char" ref="item1" name="Item1"/>
            <ColumnSchema type="char" ref="item2" name="Item2"/>
            <ColumnSchema type="char" ref="item3" name="Item3"/>
          </DataSchema>
        </MetaData>
        <Data>
          <Item>
            <Column ref="item1">Foo</Column>
            <Column ref="item2">Bar</Column>
            <Column ref="item3">Baz</Column>
          </Item>
          <Item>
            <Column ref="item1">Foo</Column>
            <Column ref="item2">Bar</Column>
            <Column ref="item3">Baz</Column>
          </Item>
        </Data>
      </Result>
    </MyResponse>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

使用 xsd,我生成了 xsd 文件,然后从这些文件中生成了 C# 类。它可以工作并且反序列化很好,但是生成的 Data 部分类不是我所期望的。

这里是相关的 xsd 部分:

      <xs:element name="Data" minOccurs="0" maxOccurs="1">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="Item" minOccurs="0" maxOccurs="unbounded">
              <xs:complexType>
                <xs:sequence>
                  <xs:element name="Column" nillable="true" minOccurs="0" maxOccurs="unbounded">
                    <xs:complexType>
                      <xs:simpleContent msdata:ColumnName="Column_Text" msdata:Ordinal="1">
                        <xs:extension base="xs:string">
                          <xs:attribute name="ref" form="unqualified" type="xs:string" />
                        </xs:extension>
                      </xs:simpleContent>
                    </xs:complexType>
                  </xs:element>
                </xs:sequence>
              </xs:complexType>
            </xs:element>
          </xs:sequence>
        </xs:complexType>
      </xs:element>

将有一个数据部分,其中可以包含可变数量的项目。每个项目可以有可变数量的列。

这是为类生成的内容:

private MyResponseResultItemColumn[][] dataField;

    [System.Xml.Serialization.XmlArrayItemAttribute("Item", IsNullable=false)]
    [System.Xml.Serialization.XmlArrayItemAttribute("Column", NestingLevel=1)]
    public MyResponseResultItemColumn[][] Data {
        get {
            return this.dataField;
        }
        set {
            this.dataField = value;
        }
    }


[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
public partial class MyResponseResultItemColumn {

    private string refField;

    private string valueField;

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string @ref {
        get {
            return this.refField;
        }
        set {
            this.refField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlTextAttribute()]
    public string Value {
        get {
            return this.valueField;
        }
        set {
            this.valueField = value;
        }
    }
}

如您所见,xsd 使 Data 成为数组数组(ItemColumn 数组的数组)。我期待并希望看到的是作为 Item 类的简单数组的 Data,其中 Item 类包含一个 ItemColumns 数组作为属性。

有什么方法可以实现吗?我希望能够键入 MyResponse.Result.Data[0].ItemColumns,而不是返回 ItemColumn 数组的 MyResponse.Result.Data[0][0]。

【问题讨论】:

  • 您使用的是什么版本的 .NET?您是否有理由不只使用“添加服务参考”?
  • 我正在使用 3.5,但很快就会迁移到 4.0。如果我只想从我拥有的 xsd 创建一个类,“添加服务引用”会对此有所帮助吗?我以前没有使用过该功能。
  • 这是一条 SOAP 消息。它来自应该具有可用 WSDL 的 SOAP 服务。这就是您应该给“添加服务参考”的内容。你将从哪里得到这些消息?磁盘文件?
  • 不要试图由此推断 XSD。 SOAP 信封(schemas.xmlsoap.org/soap/envelope)的架构,但您也不应该使用 that。听从约翰桑德斯的建议,用简单的方法去做。

标签: c# xml serialization xml-serialization deserialization


【解决方案1】:

您可以通过实现IXmlSerializable 接口来编写自己的序列化程序。这有点麻烦,但是您可以完全控制对象的形状。 This 是一篇很好的关于如何实现它的文章,我在 thread on stackoverflow 中找到了这篇文章

【讨论】:

  • 如果我只想将一些 xml 反序列化为对象,是否有必要实现此接口?有什么办法可以摆弄 xsd 来得到我想要的吗?
  • 你也许可以摆弄 xsd。实现此接口将允许您使用 XmlSerializer 对象
  • 沿着实现 IXmlSerializable 的道路前进是可行的……但在这种特殊情况下,这可能比必要或适当的努力要多得多。该消息是一个 SOAP 信封。 .NET 具有反序列化集成到通信堆栈中的 SOAP 消息的功能。这是更直接的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-19
  • 2013-04-11
  • 1970-01-01
  • 2013-10-09
  • 2021-02-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多