如何在xsd:sequence之前使用扩展插入?

时间:2015-03-18 09:50:04

标签: xml xsd

在关于扩展序列的所有示例中,所有新元素都在末尾附加。 请参阅personinfofullpersoninfohttp://www.w3schools.com/schema/schema_complex.asp

如何通过扩展定义新序列以插入新元素?示例(第二部分是错误的;如何纠正?):

<xs:complexType name="address">
  <xs:sequence>
    <xs:element name="city" type="xs:string"/>
    <xs:element name="country" type="xs:string"/>
  </xs:sequence>
</xs:complexType>

<xs:complexType name="fullpersoninfo">
  <xs:complexContent>
    <xs:sequence>
      <xs:element name="name" type="xs:string"/>
    </xs:sequence>
    <xs:extension base="address"/>
  </xs:complexContent>
</xs:complexType>

目的是验证citycountry位于多个序列末尾的一些元素。

示例:

<Employee>
  <name>A.Miller</name>
  <city>Madrid</city>
  <country>Spain</country>
</Employee>
<Flight>
  <airport>CDG</airport>
  <city>Paris</city>
  <country>France</country>
</Flight>

1 个答案:

答案 0 :(得分:6)

正如@Xstian在评论中提到的,xs:extension不起作用。详情如下,以及另一个建议......

XSD 1.0

扩展无法在 序列之前插入新元素 ;必须在 序列后附加 。根据XSD 1.0规范,XML Schema Part 1: Structures Second Edition

  

通过增加另一个来扩展另一个的复杂类型   内容模型粒子在另一个定义的内容的末尾   模型,或通过附加属性声明,或两者兼而有之。

     
      
  • 注意:此规范仅允许附加,而不允许其他类型的扩展。此决定简化了应用程序   将实例从派生类型转换为基类型所需的处理。   未来版本可能允许更多类型的扩展,需要更多   复杂的转换以实现铸造。
  •   

XSD 1.1

支持一些特殊情况,但仍然不允许在搜索序列之前插入序列。根据XSD 1.1规范,W3C XML Schema Definition Language (XSD) 1.1 Part 1: Structures

  

通过增加另一个来扩展另一个的复杂类型   内容模型粒子在另一个定义的内容的末尾   模型,或通过附加属性声明,或两者兼而有之。

     
      
  • 注意:在大多数情况下,此规范仅允许附加,而不允许其他类型的扩展。这个决定   简化了从中转换实例所需的应用程序处理   派生类型为基本类型。一个特殊情况允许   以不保证新的方式扩展所有组   材料仅出现在内容的末尾。另一个特别   case是通过 interleave 模式中的打开内容进行扩展。
  •   

替代建议:群组

您可以使用xs:extension来分解公共元素定义并在它们之前插入新元素,而不是xs:group

<强> XML

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <Employee>
    <name>A.Miller</name>
    <city>Madrid</city>
    <country>Spain</country>
  </Employee>
  <Flight>
    <airport>CDG</airport>
    <city>Paris</city>
    <country>France</country>
  </Flight>
</root>

<强> XSD

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

  <xs:group name="AddressGroup">
    <xs:sequence>
      <xs:element name="city" type="xs:string"/>
      <xs:element name="country" type="xs:string"/>
    </xs:sequence>
  </xs:group>

  <xs:complexType name="EmployeeType">
    <xs:sequence>
      <xs:element name="name" type="xs:string"/>
      <xs:group ref="AddressGroup"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="FlightType">
    <xs:sequence>
      <xs:element name="airport" type="xs:string"/>
      <xs:group ref="AddressGroup"/>
    </xs:sequence>
  </xs:complexType>

  <xs:element name="root">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="Employee" type="EmployeeType"/>
        <xs:element name="Flight" type="FlightType"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

</xs:schema>