4

我们有一个 Person 元素的定义,我们希望根据他们在做什么需要不同的元素。例如,如果他们正在添加一个人,那么需要发送不同的元素而不是更新一个人。在下面的示例中,Person 类型当前是重复的,这当然是错误的。有没有一种在 xsd 中表示它的好方法,以便我们可以重用 Person 类型。

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:complexType name="Person">
        <xs:annotation>
            <xs:documentation>This is the definition when changing a person</xs:documentation>
        </xs:annotation>
        <xs:sequence>
            <xs:element name="PartyName" type="xs:string" minOccurs="0" maxOccurs="1"/>
            <xs:element name="GenderCode" type="GenderCode_Type" minOccurs="0" maxOccurs="1"/>
            <xs:element name="BirthDate" type="xs:date" minOccurs="0" maxOccurs="1"/>
        </xs:sequence>
    </xs:complexType>
    <xs:complexType name="Person">
        <xs:annotation>
            <xs:documentation>This is the definition when adding a person</xs:documentation>
        </xs:annotation>
        <xs:sequence>
            <xs:element name="PartyName" type="xs:string" minOccurs="1" maxOccurs="1"/>
            <xs:element name="GenderCode" type="GenderCode_Type" minOccurs="1" maxOccurs="1"/>
            <xs:element name="BirthDate" type="xs:date" minOccurs="0" maxOccurs="1"/>
        </xs:sequence>
    </xs:complexType>   
</xs:schema>
4

1 回答 1

4

为 Person 元素设置两种不同类型的最简单方法是在您想到的两种不同上下文中使用 Person 的本地声明。例如,你可能会说:

<xs:element name="Add">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="Person" type="AddPerson"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>

<xs:element name="Update">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="Person" type="ChangePerson"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>

此示例假定您已将两个复杂类型重新定义为 AddPerson 和 ChangePerson。

如果您还想让这两个复杂类型显式相关,则可以通过从泛型 Person 类型的限制来派生它们。

<xs:complexType name="Person">
  <xs:annotation>
    <xs:documentation>This is the generic 
      definition for persons</xs:documentation>
  </xs:annotation>
  <xs:sequence>
    <xs:element name="PartyName" type="xs:string" 
                minOccurs="0" maxOccurs="1"/>
    <xs:element name="GenderCode" type="GenderCode_Type" 
                minOccurs="0" maxOccurs="1"/>
    <xs:element name="BirthDate" type="xs:date" 
                minOccurs="0" maxOccurs="1"/>
  </xs:sequence>
</xs:complexType>

<xs:complexType name="ChangePerson">
  <xs:annotation>
    <xs:documentation>This is the definition 
      when changing a person</xs:documentation>
  </xs:annotation>
  <xs:complexContent>
    <xs:restriction base="Person">
      <xs:sequence>
        <xs:element name="PartyName" type="xs:string" 
                    minOccurs="0" maxOccurs="1"/>
        <xs:element name="GenderCode" type="GenderCode_Type" 
                    minOccurs="0" maxOccurs="1"/>
        <xs:element name="BirthDate" type="xs:date" 
                    minOccurs="0" maxOccurs="1"/>
      </xs:sequence>        
    </xs:restriction>
  </xs:complexContent>
</xs:complexType>

<xs:complexType name="AddPerson">
  <xs:annotation>
    <xs:documentation>This is the definition 
      when adding a person</xs:documentation>
  </xs:annotation>
  <xs:complexContent>
    <xs:restriction base="Person">
      <xs:sequence>
        <xs:element name="PartyName" type="xs:string" 
                    minOccurs="1" maxOccurs="1"/>
        <xs:element name="GenderCode" type="GenderCode_Type" 
                    minOccurs="1" maxOccurs="1"/>
        <xs:element name="BirthDate" type="xs:date" 
                    minOccurs="0" maxOccurs="1"/>
      </xs:sequence>        
    </xs:restriction>
  </xs:complexContent>
</xs:complexType>  

在这里,泛型 Person 与 AddPerson 类型相同;我使用一个空洞的限制来定义 AddPerson 只是为了从泛型类型派生两种特定于操作的类型的对称性。

当然,在您的类型之间建立这种明确的关系是否真的有助于您实现目标,当然,部分取决于您的系统对模式类型定义的用途。

于 2012-10-25T00:23:21.873 回答