对属性的限制取决于 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" 属性添加另一个限制:
- 如果在 "actor" 属性中我们有字符串 "Me",则必须按照点 2)
的语法指定 "percentage" 属性
- 必须有与 "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
列表(如果您愿意,可以改用正则表达式)。
在我的 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" 属性添加另一个限制:
- 如果在 "actor" 属性中我们有字符串 "Me",则必须按照点 2) 的语法指定 "percentage" 属性
- 必须有与 "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
列表(如果您愿意,可以改用正则表达式)。