1

我想从基本类型派生元素。这种基本类型(我们称之为实体)有一个 id 属性。对于派生元素,我想为此属性添加限制(不同派生实体元素的不同限制):

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
    <xs:complexType name="Entity">
        <xs:attribute name="id">
            <xs:simpleType>
                <xs:restriction base="xs:string">
                    <xs:pattern value="[A-Z]+[0-9]+"/>
                </xs:restriction>
            </xs:simpleType>
        </xs:attribute>
    </xs:complexType>
    <xs:element name="someEntity">
        <xs:complexType>
            <xs:complexContent>
                <xs:extension base="Entity">
                    <xs:sequence>
                        <xs:element name="someAdditionalElement"/>
                    </xs:sequence>
                    <!-- I would like to restrict the attribute "id" for this entity to e.g. the pattern "SOME[0-9]+" -->
                </xs:extension>
            </xs:complexContent>
        </xs:complexType>
    </xs:element>
    <xs:element name="otherEntity">
        <xs:complexType>
            <xs:complexContent>
                <xs:extension base="Entity">
                    <xs:sequence>
                        <xs:element name="otherAdditionalElement"/>
                    </xs:sequence>
                    <!-- I would like to restrict the attribute "id" for this entity to a differtnt pattern like e.g. "OTHER[0-9]+" -->
                </xs:extension>
            </xs:complexContent>
        </xs:complexType>
    </xs:element>
</xs:schema>

这可能吗?如果可以,怎么做?

4

1 回答 1

4

在扩展类型时,您当然可以向 Entity 类型添加元素;您当然可以在限制类型时限制 id 属性。根据您的描述,您唯一不能做的事情是(1)同时扩展和限制一个类型,以及(2)“限制”一个 id 属性,它只接受大写字母字符串,允许它接受包含小数的字符串数字也是如此。(当 MiMo 说你不能做你想做的事时,这些可能就是他的想法。)

所以做你想做的事情的方法是:

  1. 定义复杂类型实体,其 id 属性允许您希望在派生类型上允许的所有形式的 id。
  2. 对于每个派生类型(在您的示例中,someEntity 和 otherEntity),首先派生实体的限制,然后是该限制的扩展 - 反之亦然,首先是扩展,然后是限制。如果您不希望这些中间类型用于其他地方的任何元素,则将它们抽象化。

当您限制属性的类型(此处为 id 属性)时,XSD 验证器需要能够轻松地看出新类型是旧类型的限制。所以你不想为实体的 id 属性使用本地定义的类型;你想要一个定义的类型。因此,您需要将 Entity 的声明替换为两个声明,如下所示:

<xs:simpleType name="uppercase-alphanumeric-string">
  <xs:restriction base="xs:string">
    <xs:pattern value="[A-Z0-9]+"/>
  </xs:restriction>
</xs:simpleType>

<xs:complexType name="Entity">
  <xs:attribute name="id" type="uppercase-alphanumeric-string"/>
</xs:complexType>

然后,您可以分两步定义元素 someEntity 的类型。首先,定义一个对 Entity 类型进行适当限制的复杂类型:

<xs:complexType name="Entity-restriction-SOME" abstract="true">
  <xs:complexContent>
    <xs:restriction base="Entity">
      <xs:attribute name="id">
        <xs:simpleType>
          <xs:restriction base="uppercase-alphanumeric-string">
            <xs:pattern value="SOME[0-9]+"></xs:pattern>
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
    </xs:restriction>
  </xs:complexContent>
</xs:complexType>

如上所述,您可以先限制后扩展,也可以先扩展后限制。我首先进行限制以避免必须为扩展类型重新指定内容模型。

然后您可以以通常的方式指定限制的扩展:

<xs:element name="someEntity">
  <xs:complexType>
    <xs:complexContent>
      <xs:extension base="Entity-restriction-SOME">
        <xs:sequence>
          <xs:element name="someAdditionalElement"/>
        </xs:sequence>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
</xs:element>

我会将 otherElement 作为练习留给读者。

于 2013-06-21T16:17:31.007 回答