将文档中所有匹配项的 xsd 枚举限制为一个值

  • 本文关键字:一个 枚举 xsd 文档 xml xsd
  • 更新时间 :
  • 英文 :


我想定义一个包含枚举的xsd模式。但是,枚举的值应在整个文档中是独占的。为了说明这一点,请考虑以下架构:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="urn:enumtest" targetNamespace="urn:enumtest" elementFormDefault="qualified">
    <xs:simpleType name="Country">
        <xs:restriction base="xs:string">
            <xs:enumeration value="CH"/>
            <xs:enumeration value="AT"/>
            <xs:enumeration value="DE"/>
        </xs:restriction>
    </xs:simpleType>
    <xs:complexType name="Address">
        <xs:sequence>
            <xs:element name="Street" type="xs:string"/>
            <xs:element name="No" type="xs:integer"/>
            <xs:element name="Code" type="xs:integer"/>
            <xs:element name="Country" type="Country"/>
        </xs:sequence>
    </xs:complexType>
    <xs:complexType name="Items">
        <xs:sequence>
            <xs:element name="Address" type="Address" maxOccurs="unbounded"/>
        </xs:sequence>
    </xs:complexType>
    <xs:element name="Document">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="Items" type="Items"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

以下两个文档应通过验证,因为它们各自包含跨文档的Country枚举的唯一值(第一个文档中的 CH,第二个文档中的 AT):

<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns="urn:enumtest" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:enumtest enumtest.xsd">
    <Items>         
        <Address>
            <Street>Street1</Street>
            <No>1</No>
            <Code>1</Code>
            <Country>CH</Country>
            </Address>              
        <Address>
            <Street>Street2</Street>
            <No>2</No>
            <Code>2</Code>
            <Country>CH</Country>
        </Address>              
        <Address>
            <Street>Street3</Street>
            <No>3</No>
            <Code>3</Code>
            <Country>CH</Country>   
        </Address>              
    </Items>
</Document>

<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns="urn:enumtest" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:enumtest enumtest.xsd">
    <Items>         
        <Address>
            <Street>Street1</Street>
            <No>1</No>
            <Code>1</Code>
            <Country>AT</Country>
        </Address>              
        <Address>
            <Street>Street2</Street>
            <No>2</No>
            <Code>2</Code>
            <Country>AT</Country>
        </Address>              
        <Address>
            <Street>Street3</Street>
            <No>3</No>
            <Code>3</Code>
            <Country>AT</Country>   
        </Address>              
    </Items>
</Document>

下一个文档应标记为无效,因为文档中存在的Country枚举中有多个值(CH 和 DE):

<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns="urn:enumtest" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:enumtest enumtest.xsd">
    <Items>         
        <Address>
            <Street>Street1</Street>
            <No>1</No>
            <Code>1</Code>
            <Country>CH</Country>
        </Address>              
        <Address>
            <Street>Street2</Street>
            <No>2</No>
            <Code>2</Code>
            <Country>CH</Country>
        </Address>              
        <Address>
            <Street>Street3</Street>
            <No>3</No>
            <Code>3</Code>
            <Country>DE</Country>
        </Address>              
    </Items>
</Document>

我已经尝试过<unique>约束,不幸的是没有多大成功。有没有办法为每个文档定义这样的独占枚举?

XSD 1.0

不能将所有Country元素限制为同时具有多个值中的相同值。 替代方案

  • XSD 可以强制文档中的所有Country元素都是通过fixed属性同时确定预选值。
  • 您的XML可以(可以说应该)重新设计以考虑公共因素 Country每个Address的值,而是存储在单个,文档中的常用位置,例如属性或子元素的ItemsDocument

XSD 1.1

xsd:assertion可以表达您的约束:

      <xs:assert test="count(distinct-values(en:Items/en:Address/en:Country)) = 1"/>

这是在完整 XSD 的上下文中:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:en="urn:enumtest" 
           targetNamespace="urn:enumtest" 
           elementFormDefault="qualified"
           xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" 
           vc:minVersion="1.1">
  <xs:simpleType name="Country">
    <xs:restriction base="xs:string">
      <xs:enumeration value="CH"/>
      <xs:enumeration value="AT"/>
      <xs:enumeration value="DE"/>
    </xs:restriction>
  </xs:simpleType>
  <xs:complexType name="Address">
    <xs:sequence>
      <xs:element name="Street" type="xs:string"/>
      <xs:element name="No" type="xs:integer"/>
      <xs:element name="Code" type="xs:integer"/>
      <xs:element name="Country" type="en:Country"/>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="Items">
    <xs:sequence>
      <xs:element name="Address" type="en:Address" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>
  <xs:element name="Document">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="Items" type="en:Items"/>
      </xs:sequence>
      <xs:assert test="count(distinct-values(en:Items/en:Address/en:Country)) = 1"/>
    </xs:complexType>
  </xs:element>
</xs:schema>

显然可以在 XSD 1.1 中使用断言来完成,但我认为在 XSD 1.0 中不能完成。

最新更新