Spectraljump
Spectraljump

Reputation: 4637

XSLT: Test if node exists regardless if it's a child or grandchild of current node

I'm working on some xslt transformations and I've just found out that there might or might not be an extra node between my current parent and it's clildren, depending on external factors. So now I have to change my xslt code in order to deal with both of these scenarios:

scenario 1:

<parent>
   <child/>
   <child/>
<parent>

scenario 2:

<parent>
   <nuisance>
      <child/>
      <child/>
   </nuisance>
<parent>

I have situations in which I test="parent/child" or otherwise use this format of accessing a parent/node.

I need something like test="parent/magic(* or none)/child"

They only way I know of that can solve this problem is to use:

<xsl:choose>
    <xsl:when test="parent/child">
       <!-- select="parent/child"-->            
    </xsl:when>

    <xsl:otherwise>
       <!-- select="parent/*/child"-->      
    </xsl:otherwise>
</xsl:choose>

But this will triple my code in size and will be a lot of manual labour...

Help much appreciated!

Upvotes: 1

Views: 2948

Answers (2)

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243479

I have situations in which I test="parent/child" or otherwise use this format of accessing a parent/node.

I need something like test="parent/magic(* or none)/child"

This expression may be faster:

parent/child or parent/*/child

than the expression:

parent/child|parent/*/child

Almost any XPath engine will immediately stop the evaluation at the first occurence of parent/child or at the first occurence of parent/someElement/child

On the other side, the second expression selects the union of all parent/child and parent/*/child elements and there may be many such elements.

Even worse is:

<xsl:apply-templates select="parent/child|parent/*/child"/>        

A test, as the original question needs, is very different from applying templates on all nodes that match this test. Just testing for a condition can be significantly more efficient. The OP hasn't indicated in any way that the test is in any way connected to applying templates.

Upvotes: 0

Wayne
Wayne

Reputation: 60414

Why not simply select the union of the two?

<xsl:apply-templates select="parent/child|parent/*/child"/>

This will select the correct nodes in both cases.

Upvotes: 5

Related Questions