1

我正在重写一个旧系统,我使用 xsd.exe 从 XML 文档创建了一个模式,然后使用 xsd.exe/xsd2code 从 xsd 生成了 .NET 代码。然而,似乎存在一个缺陷,可能是在原始 xml 文档的设计或它的生成方式中,但我对架构的了解不够,无法纠正问题。这是一个说明问题的清理示例:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
  <xs:element name="ABC">
    <xs:complexType>
      <xs:all>
        <xs:element ref="ABC_HEADER"/>
        <xs:element name="BODY_A" minOccurs="0" />
        <xs:element name="BODY_B" minOccurs="0" />
        <xs:element name="BODY_C" minOccurs="0" />
      </xs:all>
    </xs:complexType>
  </xs:element>
</xs:schema>

这个想法是 ABC 类是一个消息,它包含一个标题和一个可以是各种类型的单个主体元素(我没有设计这个)。当生成的类被序列化时,我在输出 XML 中获得了每个主体类之一:

<?xml version="1.0" encoding="utf-8"?>
<ABC>
  <ABC_HEADER>
  </ABC_HEADER>
  <BODY_A></BODY_A>
  <BODY_B></BODY_B>
  <BODY_C></BODY_C>

鉴于我无法更改设计并且生成的 XML 需要与旧版 XML 匹配,这是<xs:all>表示这一点的正确方式,还是 <xs:sequence>或其他更好的选择?

或者,我是否需要编写一些自定义(预)序列化代码来生成正确的输出?

编辑:尽管最后得到了很好的答案,但我不得不为<ABC>元素编写自定义序列化代码,但结合了<ABC_HEADER>and<BODY_>元素的普通序列化(删除了 xml 声明)

4

2 回答 2

3

你试过这个吗?

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
                                    elementFormDefault="qualified">
  <xs:element name="ABC_HEADER" type="xs:string"/>
  <xs:element name="ABC">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="ABC_HEADER"/>
        <xs:choice>
          <xs:element name="BODY_A"/>
          <xs:element name="BODY_B"/>
          <xs:element name="BODY_C"/>
        </xs:choice>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

编辑:您是否尝试过使用以下方式继承架构:

<?xml version="1.0" encoding="utf-8" ?>
<xs:schema elementFormDefault="qualified" 
           xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xs:complexType name="ABC">
    <xs:sequence>
      <xs:element ref="ABC_HEADER" />
      <xs:element name="BODY" type="BODY" />
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="BODY">
    <xs:sequence />
  </xs:complexType>

  <xs:complexType name="BODY_A">
    <xs:complexContent mixed="false">
      <xs:extension base="BODY">
        <!-- define BODY_A schema here -->
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

  <xs:complexType name="BODY_B">
    <xs:complexContent mixed="false">
      <xs:extension base="BODY">
        <!-- define BODY_B schema here -->
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

  <xs:complexType name="BODY_C">
    <xs:complexContent mixed="false">
      <xs:extension base="BODY">
        <!-- define BODY_C schema here -->
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

</xs:schema>
于 2012-09-18T13:30:36.653 回答
0

如果BODY_A, BODY_B, 和的顺序BODY_C比使用sequence元素重要,否则可以使用all元素。听起来您想使用该sequence元素。

all 元素指定子元素可以以任何顺序出现,并且每个子元素可以出现零次或一次。

来源

序列元素指定子元素必须出现在序列中。每个子元素可以出现 0 到任意次数。

来源

我还将继续使用该minOccurs="0"指标。

完整架构参考

于 2012-09-18T14:37:25.310 回答