如何根据上下文确定XSD元素是必需的还是不必需的?

如何根据上下文确定XSD元素是必需的还是不必需的?,xsd,xsd-validation,Xsd,Xsd Validation,我们有一个Person元素的定义,其中我们希望根据需要使用不同的元素 他们正在做什么。例如,如果他们正在添加一个人,则需要不同的元素 发送而不是更新一个人。在下面的示例中,人员类型当前是重复的,这 当然是错的。是否有一种在xsd中表示这一点的好方法,以便我们可以重用Person类型 <?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

我们有一个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>
<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元素提供两种不同类型的最简单方法是在您想到的两种不同上下文中使用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类型来派生它们

<?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>
<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时使用了一个空洞的限制,只是为了从泛型类型派生两个操作特定类型的对称性

当然,类型之间的这种显式关系是否真的有助于实现目标,部分取决于系统如何使用模式类型定义