首页 文章

XML Schema 1.1:断言具有匹配id值的允许兄弟节点的数量

提问于
浏览
4

我有以下(打算有效)XML:

<Series>
    <A>
        <id>1</id>
    </A>
    <B>
        <id>1</id>
    </B>
    <B>
        <id>1</id>
    </B>
    <B>
        <id>2</id>
    </B>
</Series>

使用XSD 1.1和XPath 2.0,我想断言名为"B"的最大元素数与"A"共享相同的"id"值 . 具体来说,我想将名称"B"的元素数量限制为具有"id" = 1,具体为2次 . 我没有't care how many elements named B there are with other 2647980 values that don'匹配A的id = "1"(所以可能有一百万 <B><id>2</id></B> ,它仍然会验证 .

这是我尝试的XML Schema 1.1强制执行此操作,在assert指令中使用XPath 2.0表达式:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="Series" type="series"/>
  <xs:complexType name="series">
    <xs:sequence>
        <xs:element name="A" type="a"/>
        <xs:element name="B" type="b" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="a">
    <xs:sequence>
      <xs:element name="id" type="xs:string"/>
    </xs:sequence>
    <xs:assert test="count(following-sibling::element(B)[id/text() = ./id/text()]) eq 2"/>
  </xs:complexType>
  <xs:complexType name="b">
    <xs:sequence>
        <xs:element name="id" type="xs:string"/>
    </xs:sequence>
  </xs:complexType>
</xs:schema>

但是我的断言总是因cvc断言错误消息而失败 . 如果我试图放松断言只是 <xs:assert test="count(following-sibling::element(B)) ge 1"/> ,它仍然会失败,所以看起来XML Schema 1.1无法处理所有XPath 2.0构造?

通常,有没有办法在XML Schema 1.1中对兄弟进行断言?谢谢!

2 回答

  • 0

    XML Schema 1.1断言可以处理所有XPath 2.0,但根据规范(section 3.13.4

    1.3从“部分”·模式后验证信息集中,按照[XDM]中的描述构建数据模型实例 . [XDM]实例的根节点由E构成;数据模型实例仅包含从[attributes],[children]和E的后代构造的节点和节点 . 注意:这种结构的结果是试图在断言中引用兄弟姐妹或祖先 . E或E本身之外的输入文档的任何部分都将失败 . 这样的尝试引用本身并不是错误,但用于评估它们的数据模型实例不包括E之外的文档的任何部分的任何表示,因此它们不能被引用 .

    (我的大胆) . 在评估断言时,您只有以托管断言的元素为根的子树,因此如果要在树的不同部分中断言元素之间的关系,则必须将断言置于其共同的祖先之一上 .

    我认为它是这样设计的,允许验证解析器在解析期间,在相关元素的末尾评估断言,而不是必须等到整个树构建完毕,然后整体评估所有断言 .

  • 3

    我找到了如何控制允许的兄弟姐妹的问题的答案 . 关键是不要将断言放在兄弟的类型中,而是放在父节点中 . 断言条款也因此改变为: every $aid in child::element(A)/id satisfies (count(child::element(B)[child::id = $aid]) le 2) . 至于我最后提出的关于在XSD 1.1中对兄弟进行断言的更普遍的问题,我还没有开始明白这一点 .

    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
        <xs:element name="Series" type="series"/>
        <xs:complexType name="series">
            <xs:sequence>
                <xs:element name="A" type="a"/>
                <xs:element name="B" type="b" maxOccurs="unbounded"/>
            </xs:sequence>
            <xs:assert test="every $aid in child::element(A)/id satisfies (count(child::element(B)[child::id = $aid]) le 2)"/>
        </xs:complexType>
        <xs:complexType name="a">
            <xs:sequence>
                <xs:element name="id" type="xs:string"/
            </xs:sequence>
        </xs:complexType>
        <xs:complexType name="b">
             <xs:sequence>
                <xs:element name="id" type="xs:string"/>
             </xs:sequence>
        </xs:complexType>
     </xs:schema>
    

相关问题