如何断言所有子节点在XPath中都有一定的属性值?

时间:2009-07-15 23:13:16

标签: xml xpath xslt

给出以下部分XML文档:

<section>
    <entry typeCode="DRIV">
        <act classCode="AT" moodCode="DEF">
            <statusCode code="completed"/>
        </act>
    </entry>
    <entry typeCode="DRIV">
        <act classCode="ACT" moodCode="DEF">
            <statusCode code="completed"/>
        </act>
    </entry>
    <entry typeCode="DRIV">
        <act classCode="ACT" moodCode="DEF">
            <statusCode code="completed"/>
        </act>
    </entry>
    <entry typeCode="DRIV">
        <act classCode="ACT" moodCode="DEF">
            <statusCode code="completed"/>
        </act>
    </entry>

    <section>
        <entry typeCode="DRIV">
            <act classCode="AT" moodCode="DEF">
                <statusCode code="completed"/>
            </act>
        </entry>
        <entry typeCode="DRIV">
            <act classCode="ACT" moodCode="DEF">
                <statusCode code="completed"/>
            </act>
        </entry>
    </section>
</section>

我想声明所有作为外部<section>元素后代但不是内部<section>元素的元素的元素都为classCode属性赋值{{1 }}

换句话说,鉴于上面的例子,我不需要在第二个"ACT"元素中断言两个<act>子元素的值。此外,可以有一个或多个嵌套的<section>元素(没有最大值)。

我尝试了以下XPath表达式,

<entry>

如果<xsl:when test="cda:section/cda:entry/cda:act//@classCode='ACT'"/> 元素中的任何一个元素具有<act>以外的属性classCode的值,则断言应该失败。我正在寻找有关如何更改我的XPath表达式以满足此要求的建议。

4 个答案:

答案 0 :(得分:4)

你只是颠倒了条件:

<xsl:when test="not(cda:section/cda:entry/cda:act//@classCode != 'ACT')"/>

如果任何 not()不等于true,则@classCode内的表达式将生成'ACT'。如果没有 false等于@classCode,它只会返回'ACT'。然后我们也将其反转,并获得预期的效果。

答案 1 :(得分:1)

假设上下文节点是外部<section>的直接父节点,您可以使用以下测试执行此操作:

<xsl:when test="count(cda:section/cda:entry/cda:act) = count(cda:section/cda:entry/cda:act[@classCode = 'ACT'])">
    <foo/>
</xsl:when>

这可以通过计算属于<act>的{​​{1}}元素的数量来实现,这些元素是<entry>的直接后代(跳过子<section>中的任何内容)。然后,它会计算<section>的{​​{1}}个<act>的数量,并查看这两个计数是否匹配。由于节点不可能匹配第二个计数而不匹配第一个计数,因此您知道所有非嵌套后代classCode具有正确的ACT

答案 2 :(得分:0)

嗯。

<xsl:when test="cda:section/cda:entry/cda:act/@classcode = 'ACT'" /> 

应该做你想要的。

答案 3 :(得分:0)

  

如果<act>元素中的任何一个有   属性classCode的值   除"ACT"以外的断言   应该失败。

另一种可能在语义上更明显的变体:

count(cda:section/cda:entry/cda:act[@classCode != 'ACT']) = 0