开发者

Check if node in path of a node with a specific attribute

开发者 https://www.devze.com 2023-01-31 18:52 出处:网络
What is the fastest way to find whether the current node is in path of a node with a specific attribute, given this xml structure:

What is the fastest way to find whether the current node is in path of a node with a specific attribute, given this xml structure:

<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>

I have a xslt variable to tell me what开发者_运维问答 the current active node is.

I want to execute some code if the current node is in path of the node with the @name x.

So that if the active node is the item with @name y the code should execute, if the current active node is item with @name z it shouldn't.

My best solution so far is:

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

But as there are 30k+ item nodes this is taking forever to render, is there a faster way? (XSLT/XPATH 2 is not an option)


The best approach strongly depends on the whole transformation.

One could assume that pattern matching is optimized, so:

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

Also, you could use modes like:

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

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

Or a parameter like:

<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>


To add to the good answer by @Alejandro:

In the name of completeness, in XSLT one could define a key:

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

And then reference this key like this:

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

In theory, the use of such key might be faster than other methods, if the test for any specific node is performed (in average) more than once.

However, you may need a lot of memory for the indices.

0

精彩评论

暂无评论...
验证码 换一张
取 消