对属性的限制取决于 XSD 1.1 中的其他属性

Restriction on attributes depending on other attributes in XSD 1.1

在我的 XML 文件中按以下方式定义了一个 "MultipleChoice" 节点:

<multipleChoice  numberOfChoices="" percentage="0"> text

对应我的XSD schema 的需要,我的XSD 定义中提到的是下面一个:

<xs:element name="multipleChoice" type="MultipleChoiceType"/>

<xs:complexType name="MultipleChoiceType" mixed="true">
  <xs:sequence>
    <xs:element  minOccurs="0" maxOccurs="unbounded" ref="choice"/>
  </xs:sequence>
  <xs:attribute name="numberOfChoices" type="xs:integer" use="required"/>
  <xs:attribute name="percentage" type="xs:integer" use="required"/>
  <xs:assert test="count(./choice) = @numberOfChoices" />
</xs:complexType>

我需要为我的 "percentage" 属性添加另一个限制:

  1. 如果在 "actor" 属性中我们有字符串 "Me",则必须按照点 2)
  2. 的语法指定 "percentage" 属性
  3. 必须有与 "numberOfChoices" 属性指定的一样多的整数,所有整数仅由一个白色 space 分隔。

例如:如果"numberOfChoices"="3" 那么在"percentage"中我们需要3个整数,只用一个白色分隔space,例如"percentage"= " 30 40 30".

如果 "actor" 属性中存在字符串 "Me" 之外的其他内容,我们不关心 "numberOfChoices" 和 "percentage" 属性中发生了什么。

我需要 "percentage" 属性,我还需要接受以下情况:

<multipleChoice actor="" bar="" points="0" numberOfChoices="3" percentage="">

因为在 "actor" 属性中没有字符串 "Me" 我不必检查 "percentage" 属性中的内容。但无论如何它都必须在那里。

提前致谢!

首先,在你的示例中 percentage 是一个 xs:int 属性,你需要将其更改为 xs:int 列表(and/or 添加一个正则表达式,如果你值之间真的只需要一个空格)。

然后就可以用xpath tokenize function百分比值进行除法和计数(例子:tokenize('1 2 3 4 5', '\s') returns ('1', '2', '3', '4', '5').

示例架构:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
    xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" vc:minVersion="1.1">

    <xs:element name="multipleChoice" type="MultipleChoiceType"/>

    <xs:complexType name="MultipleChoiceType" mixed="true">
        <xs:sequence>
            <xs:element  minOccurs="0" maxOccurs="unbounded" name="choice" type="xs:string"/>
        </xs:sequence>
        <xs:attribute name="numberOfChoices" type="xs:integer" use="required"/>
        <!-- Percentage is now a list of xs:int -->
        <xs:attribute name="percentage" use="required">
            <xs:simpleType>
                <xs:list itemType="xs:integer"/>
            </xs:simpleType>
        </xs:attribute>
        <!-- New actor attribute -->
        <xs:attribute name="actor" type="xs:string" use="required"/>
        <xs:assert test="count(./choice) = @numberOfChoices" />
        <!-- The count only needs to be satisfied if actor=Me -->
        <xs:assert test="@actor != 'Me' or count(tokenize(normalize-space(string(@percentage)),'\s')) =  @numberOfChoices"/>
    </xs:complexType>

</xs:schema>

请注意,我使用了 normalize-space xpath function 函数,因为 ' 1 2 3' 是一个有效的 xs:int 列表(如果您愿意,可以改用正则表达式)。