Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p><strong>Use</strong>:</p> <pre><code>.//*[@auto and $tempId = ancestor::*[@auto][1]/@tempId] </code></pre> <p>This selects all descendent elements (of the context node) that have an <code>auto</code> attribute and whose first ancestor that has <code>auto</code> attribute also has a <code>tempId</code> attribute with the same value as that of the <code>tempId</code> attribute of the context node (the latter being stored in the <code>$tempId</code> variable).</p> <p>Here we assume that no two different elements have the same value of their <code>tempId</code> attributes.</p> <p><strong>A quick XSLT-based verification</strong>:</p> <pre><code>&lt;xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt; &lt;xsl:output omit-xml-declaration="yes" indent="yes"/&gt; &lt;xsl:template match="a"&gt; &lt;xsl:variable name="tempId" select="@tempId"/&gt; &lt;xsl:copy-of select= ".//*[@auto and $tempId = ancestor::*[@auto][1]/@tempId]"/&gt; &lt;/xsl:template&gt; &lt;/xsl:stylesheet&gt; </code></pre> <p><strong>When this transformation is applied on the provided XML document</strong>:</p> <pre><code>&lt;root&gt; &lt;a auto="1" tempId="current"&gt; &lt;b&gt; &lt;c auto="1"&gt; &lt;d auto="1"&gt;&lt;/d&gt; &lt;/c&gt; &lt;/b&gt; &lt;e auto="1"&gt; &lt;f&gt; &lt;g auto="1"&gt;&lt;/g&gt; &lt;/f&gt; &lt;/e&gt; &lt;/a&gt; &lt;/root&gt; </code></pre> <p><strong>the wanted, correct result (the two elements <code>c</code> and <code>e</code>) is produced</strong>:</p> <pre><code>&lt;c auto="1"&gt; &lt;d auto="1"/&gt; &lt;/c&gt; &lt;e auto="1"&gt; &lt;f&gt; &lt;g auto="1"/&gt; &lt;/f&gt; &lt;/e&gt; </code></pre> <p><strong>The performance cannot be improved only within the XPath expression</strong> and the inefficiency is due to having to use the <code>//</code> XPath pseudo-operator.</p> <p><strong>If using XSLT, it is possible to have an efficient solution using keys</strong>:</p> <pre><code>&lt;xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt; &lt;xsl:output omit-xml-declaration="yes" indent="yes"/&gt; &lt;xsl:strip-space elements="*"/&gt; &lt;xsl:key name="kfirstDescendents" match="*[@auto]" use="generate-id(ancestor::*[@auto][1])"/&gt; &lt;xsl:template match="a"&gt; &lt;xsl:copy-of select= "key('kfirstDescendents', generate-id())"/&gt; &lt;/xsl:template&gt; &lt;/xsl:stylesheet&gt; </code></pre> <p><strong>This transformation produces the same result as the first, and is significantly faster</strong> on documents with many nested elements that have an <code>auto</code> attribute.</p> <p>If use of XSLT is absolutely ruled out, one can achieve the same effect as XSLT keys with the use of hash tables (sorry, don't know PHP).</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