使用标头和多个正文类型更正XML消息的架构

时间:2012-09-18 11:28:22

标签: xml visual-studio-2010 serialization xsd

我正在重写一个旧系统,我使用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类是一个消息,它包含一个标题和一个可以是各种类型的单个body元素(我没有设计这个)。当生成的类被序列化时,我得到输出XML中每个body类中的一个:

<?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>选择正确的方式来表示这个或者&lt; xs:sequence>或其他更好的选择选择?

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

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

2 个答案:

答案 0 :(得分: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>

答案 1 :(得分:0)

如果BODY_ABODY_BBODY_C的顺序比使用sequence元素重要,否则您可以使用all元素。听起来你想要使用sequence元素。

  

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

Source

  

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

Source

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

Full Schema Reference