XSD 中的条件必需元素

Conditional required elements in an XSD

我有一个 xml 架构的要求,它接受客户或客户 ID 的请求。如果客户 ID 为 0 那么我们需要客户数据,如果它 > 0 那么客户数据是可选的(他们可以提交修改)。我的 XSD 目前看起来像这样;

<xs:complexType>


    <xs:any>
      <xs:element name="UserID" type="xs:string" minOccurs="1"/>
      <xs:element name="Password" type="xs:string" minOccurs="1"/>
      <xs:element name="ReferenceNumber" type="xs:string" minOccurs="0"  maxOccurs="1"/>
      <xs:element name="CustomerId" minOccurs="1" maxOccurs="1" type="xs:integer"/>
      <xs:element ref="WhereSigned"/>
      <xs:element name="ContactName" type="xs:string" minOccurs="0"  maxOccurs="1"/>
      <xs:element name="ContactTelephone" type="xs:string" minOccurs="0"  maxOccurs="1"/>
      <xs:element name="ContactFax" type="xs:string" minOccurs="0"  maxOccurs="1"/>
      <xs:element name="ContactEmail" type="xs:string" minOccurs="0"  maxOccurs="1"/>
      <xs:element ref="MainApplicant"  maxOccurs="1"/>
      <xs:element ref="JointApplicant" minOccurs="0" maxOccurs="1"/>
      <xs:element ref="Asset" minOccurs="0" maxOccurs="1"/>
    </xs:any>


</xs:complexType>

我需要这样的东西......(我希望它是这么简单,可惜不是......)

<xs:complexType>
  <xs:choice>

    <xs:any>
      <xs:element name="UserID" type="xs:string" minOccurs="1"/>
      <xs:element name="Password" type="xs:string" minOccurs="1"/>
      <xs:element name="ReferenceNumber" type="xs:string" minOccurs="0"  maxOccurs="1"/>
      <xs:element name="CustomerId" minOccurs="1" maxOccurs="1">
        <xs:simpleType>
          <xs:restriction base="xs:integer">
            <xs:minInclusive value="0"/>
            <xs:maxInclusive value="0"/>
          </xs:restriction>
        </xs:simpleType>
      </xs:element>
      <xs:element ref="WhereSigned"/>
      <xs:element name="ContactName" type="xs:string" minOccurs="0"  maxOccurs="1"/>
      <xs:element name="ContactTelephone" type="xs:string" minOccurs="0"  maxOccurs="1"/>
      <xs:element name="ContactFax" type="xs:string" minOccurs="0"  maxOccurs="1"/>
      <xs:element name="ContactEmail" type="xs:string" minOccurs="0"  maxOccurs="1"/>
      <xs:element ref="MainApplicant"  maxOccurs="1"/>
      <xs:element ref="JointApplicant" minOccurs="0" maxOccurs="1"/>
      <xs:element ref="Asset" minOccurs="0" maxOccurs="1"/>
    </xs:any>

    <xs:any>
      <xs:element name="UserID" type="xs:string" minOccurs="1"/>
      <xs:element name="Password" type="xs:string" minOccurs="1"/>
      <xs:element name="ReferenceNumber" type="xs:string" minOccurs="0"  maxOccurs="1"/>
      <xs:element name="CustomerId" minOccurs="1" maxOccurs="1">
        <xs:simpleType>
          <xs:restriction base="xs:integer">
            <xs:minInclusive value="1"/>
          </xs:restriction>
        </xs:simpleType>
      </xs:element>
      <xs:element ref="Asset" minOccurs="0" maxOccurs="1"/>
    </xs:any>

   </xs:choice>
</xs:complexType>

有 XSD 专家(这些专家真的存在吗?!)可以提供帮助或建议吗?

这在 XSD 1.1 中是可能的;下面是一个简化的示例,假设当 CustomerId 等于零时 MainApplicant 和 WhereSigned 是强制性的。

<?xml version="1.0" encoding="utf-8" ?>
<!-- XML Schema generated by QTAssistant/XSD Module (http://www.paschidev.com) -->
<xsd:schema elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xtm="http://paschidev.com/schemas/metadata/xtm">
    <xsd:complexType name="Request">
        <xsd:all>
            <xsd:element name="UserID" type="xsd:string" />
            <xsd:element name="Password" type="xsd:string" />
            <xsd:element name="ReferenceNumber" type="xsd:string" minOccurs="0"/>
            <xsd:element name="CustomerId" type="xsd:integer"/>
            <xsd:element ref="WhereSigned" minOccurs="0"/>
            <xsd:element name="ContactName" type="xsd:string" minOccurs="0" />
            <xsd:element name="ContactTelephone" type="xsd:string" minOccurs="0" />
            <xsd:element name="ContactFax" type="xsd:string" minOccurs="0" />
            <xsd:element name="ContactEmail" type="xsd:string" minOccurs="0" />
            <xsd:element ref="MainApplicant" minOccurs="0" />
            <xsd:element ref="JointApplicant" minOccurs="0" />
            <xsd:element ref="Asset" minOccurs="0" />
        </xsd:all>
        <xsd:assert test="CustomerId[. eq 0] and WhereSigned and MainApplicant or CustomerId[. ne 0]" />
    </xsd:complexType>
    <xsd:element name="Asset"/>
    <xsd:element name="MainApplicant" />
    <xsd:element name="JointApplicant" />
    <xsd:element name="WhereSigned" />  
</xsd:schema>

最低有效 XML,当 CustomerId 为零时:

<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Request">
    <UserID>UserID1</UserID>
    <Password>asodasqZX==</Password>
    <CustomerId>0</CustomerId>
    <WhereSigned/>
    <MainApplicant/>
</root>

当 CustomerId 非零时,这是最小值 XML:

<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Request">
    <UserID>UserID1</UserID>
    <Password>asodasqZX==</Password>
    <CustomerId>1</CustomerId>
</root>

条件容易控制(见@test表达式);根据需要添加常规 XSD 约束(例如,如果您的 CustomerId 需要大于或等于零,则将其设为非负整数等)