Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Well, a couple of observations:</p> <ol> <li><p>You don't need the leading slashes in <code>match='//Page'</code>. The XPath in the <code>match</code> attribute is used to select a template, not navigate to a node.</p></li> <li><p>You don't need a <code>depth</code> parameter; since the depth of a <code>Page</code> is the number of <code>Page</code> ancestors it has, you can just use <code>count(ancestor::Page)</code> to calculate the depth.</p></li> <li><p>If you want to get the <code>Active</code> attribute by walking up the tree of <code>Page</code> elements, use <code>ancestor-or-self::Page[last()]/@Active</code>. The ancestor-or-self axis is a list of nodes that starts with the context node and includes its parent, its parent's parent, and so on, until the TLE is reached. The <code>Page</code> part finds only <code>Page</code> elements on that axis, and the <code>[last()]</code> predicate finds the last of those <code>Page</code> elements, which will always be the highest-level <code>Page</code> element.</p></li> <li><p>I strongly suspect that your use of <code>count(//Page)</code> is not going to serve you well in the long run. That counts every single <code>Page</code> element in the source tree, irrespective of where it is found. Is that really what you want? Or do you want to know where the current <code>Page</code> element is relative to its sibling <code>Page</code> elements? If so, you can just do <code>position() != 1 and position() != last()</code>. This works because <code>position()</code> returns the context node's position relative to its expression context. That is, when <code>xsl:apply-templates select='*'</code> is invoked, it creates a set of elements and finds a matching template for each. That's the expression context; the third element in that list will have a <code>position()</code> of 3.</p></li> <li><p>There's no need to do <code>test='count(Page)</code>. <code>test='Page'</code> does the same thing; it evaluates to true if there's any child <code>Page</code> element. It's both more readable and very likely faster.</p></li> </ol> <p><strong>Edit</strong></p> <p>Incorporated Tomalak's observation (see comments).</p> <p><strong>Edit</strong></p> <p>You know, I should actually read these questions. In your context, to give a parent element a class when it or one of its <em>children</em> is active, the opposite of what I've done, you'd do:</p> <pre><code>&lt;xsl:if test="@Active='True' or Page[@Active = 'True']"&gt; &lt;xsl:text&gt; active&lt;/xsl:text&gt; &lt;/xsl:if&gt; </code></pre> <p>But Tomalak's example, which uses the <code>descendant-or-self</code> axis, is more likely what you want to use, if the idea is to activate a menu if anything anywhere within it is active. You could also do this:</p> <pre><code>&lt;xsl:if test="@Active='True' or .//Page[@Active = 'True']"&gt; &lt;xsl:text&gt; active&lt;/xsl:text&gt; &lt;/xsl:if&gt; </code></pre> <p>as ".//" is really just a shortcut for <code>descendant::</code>.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload