根据XSD 1.1中的其他属性限制属性

时间:2015-06-13 09:48:49

标签: xml xsd

在我的XML文件中,以下列方式定义“MultipleChoice”节点:

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

对应于我的XSD架构的需求,我提到的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>

我需要的是为我的“百分比”属性添加另一个限制:

  1. 如果在“actor”属性中我们有字符串“Me”,则必须按照点2)的语法指定“percentage”属性。
  2. 必须有“numberOfChoices”属性指定的整数,所有整数都只用一个空格分隔。
  3. 例如:如果“numberOfChoices”=“3”那么在“百分比”中我们需要3个整数,只用一个空格分隔,例如“percentage”=“30 40 30”。

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

    我需要“百分比”属性,我需要接受以下情况:

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

    由于在“actor”属性中没有字符串“Me”,因此我不必检查“percentage”属性中的内容。但无论如何它必须存在。

    提前致谢!

1 个答案:

答案 0 :(得分:1)

首先,在您的示例中percentagexs:int属性,您需要将其更改为xs:int列表(和/或如果您确实只需要一个,请添加正则表达式值之间的空间。)

然后你可以使用xpath tokenize function来划分和计算百分比值(例如:tokenize('1 2 3 4 5','\ s')返回('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列表(如果您希望可以使用正则表达式)。

相关问题