检查具有特定属性的节点的路径中的节点

时间:2010-12-23 12:35:34

标签: xml xslt xpath

在给定此xml结构的情况下,查找当前节点是否在具有特定属性的节点的路径中的最快方法是什么:

<root>
<item>
    <item name="x">
        <item></item>
        <item name="y"></item>
        <item></item>
    </item>
    <item></item>
    <item></item>
</item>
<item>
    <item name="z"></item>
    <item></item>
</item>

我有一个xslt变量来告诉我当前的活动节点是什么。

如果当前节点位于具有@name x。

的节点的路径中,我想执行一些代码

因此,如果活动节点是具有@name y的项目,则代码应该执行,如果当前活动节点是具有@name z的项目,则不应该执行。

到目前为止,我最好的解决方案是:

ancestor-or-self::item[@name = 'x']

但由于有30k +项目节点需要永久渲染,有更快的方法吗? (XSLT / XPATH 2不是一个选项)

2 个答案:

答案 0 :(得分:2)

最好的方法很大程度上取决于整个转型。

可以假设模式匹配已经过优化,因此:

<xsl:template match="item[@name='x']//*">

此外,您可以使用以下模式:

<xsl:template match="item[@name='x']">
    <xsl:apply-templates mode="descandants-in-path">
</xsl:template>

<xsl:template match="node()" mode="descandants-in-path">

或者参数如:

<xsl:template match="item[@name='x']">
    <xsl:apply-templates>
        <xsl:with-param name="pIsInPath" select="true()"/>
    </xsl:apply-templates>
</xsl:template>

<!-- Tunnel rule -->
<xsl:template match="*">
    <xsl:param name="pIsInPath"/>
    <xsl:apply-templates>
        <xsl:with-param name="pIsInPath" select="$pIsInPath"/>
    </xsl:apply-templates>
</xsl:template>

答案 1 :(得分:0)

要添加@Alejandro的好答案:

在完整性的名称中,在XSLT中可以定义一个键

<xsl:key name="kInSubtreebyId" 
         match="item[ancestor-or-self::item[@name='x']]"
         use="generate-id()"/>

然后像这样引用此键

<xsl:if test="key('kInSubtreebyId', generate-id())">
 . . . . . . .
</xsl:if>

理论上,如果对任何特定节点的测试执行(平均)不止一次,则使用此类密钥可能比其他方法更快。

但是,索引可能需要大量内存。