如何在XSD断言XPath中访问父元素?

3

我想写一个断言,使@row@column的值小于或等于父元素<structure>@rows@columns 的值。

<xs:element name="structure">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="cell" maxOccurs="unbounded">
                <xs:complexType>
                    <xs:attribute name="row" type="xs:positiveInteger"/>   
                    <xs:attribute name="column" type="xs:positiveInteger"/>
                    <xs:assert test="@row le @rows"/>
                    <xs:assert test="@column le @columns"/>
                </xs:complexType>
            </xs:element>
        </xs:sequence>
        <xs:attribute name="rows" type="xs:positiveInteger" use="optional"/>
        <xs:attribute name="columns" type="xs:positiveInteger" use="optional"/>
    </xs:complexType>
</xs:element>

我的断言放错了位置吗?我该使用什么XPath表达式指定父节点?我的编辑器不允许我写..@rows


../@rows 怎么样? - har07
没成功。我尝试了@rows的值为21,@row的值为1,但是出现了以下错误信息:描述:对于模式类型“#AnonType_cellstructurebodypuzzle”上的元素“cell”,断言评估('@row le ../@rows')未成功。 - Misenus
2
@har07:从XPath的角度来看,这似乎是合理的,但XSD断言无法访问超出所管辖元素范围之外的节点。解决方案是将断言移动到最高上下文中,以表达约束条件。 - kjhughes
1个回答

4
一个断言XPath不能超出其上下文范围。
因此,将您的断言移至“结构”元素,并使用“every ... satisfies”断言测试。
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
           elementFormDefault="qualified"
           vc:minVersion="1.1">
    <xs:element name="structure">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="cell" maxOccurs="unbounded">
                    <xs:complexType>
                        <xs:attribute name="row" type="xs:positiveInteger"/>   
                        <xs:attribute name="column" type="xs:positiveInteger"/>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
            <xs:attribute name="rows" type="xs:positiveInteger" use="optional"/>
            <xs:attribute name="columns" type="xs:positiveInteger" use="optional"/>
            <xs:assert test="every $r in cell/@row satisfies @rows >= $r"/>
            <xs:assert test="every $c in cell/@column satisfies @columns >= $c"/>
        </xs:complexType>
    </xs:element>
</xs:schema>

顺便提一下,Saxon XSD 1.1处理器识别形式为“每个X都满足T”的断言,并将它们特殊处理,因此诊断会告诉您哪个X未能满足T。 - Michael Kay
@MichaelKay,做得好 - 比简单的通过/失败更有帮助。 - kjhughes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接