Note that there are some explanatory texts on larger screens.

plurals
  1. POCan I make this xpath search faster?
    text
    copied!<p>xml:</p> <p><code> &lt;root&gt;<br/> &nbsp;&lt;a&nbsp;auto='1'&gt;<br/> &nbsp;&nbsp;&lt;b&gt;<br/> &nbsp;&nbsp;&nbsp;&lt;c auto="1"&gt;<br/> &nbsp;&nbsp;&nbsp;&nbsp;&lt;d auto="1"&gt;&lt;/d&gt;<br/> &nbsp;&nbsp;&nbsp;&lt;/c&gt;<br/> &nbsp;&nbsp;&lt;/b&gt;<br/> &nbsp;&nbsp;&lt;e auto="1"&gt;<br/> &nbsp;&nbsp;&nbsp;&lt;f&gt;<br/> &nbsp;&nbsp;&nbsp;&nbsp;&lt;g auto="1"&gt;&lt;/g&gt;<br/> &nbsp;&nbsp;&nbsp;&lt;/f&gt;<br/> &nbsp;&nbsp;&lt;/e&gt;<br/> &nbsp;&lt;/a&gt;<br/> &lt;/root&gt;<br/> </code> <br/></p> <p>The job is: find all elements that:<br/> 1, Is descendant of context element<br/> 2, Have '<strong>auto</strong>' attribute<br/> 3, Highest level (have no ancestor <strong>with auto attribute</strong> between self and the context element)<br/></p> <p>So, if the context node is <strong>a</strong>, <strong>c</strong> and <strong>e</strong> should be returned.<br/></p> <p>I'v implement it in my php class:<br/> <code> $tempId='XDFAY69LA';<br/> $this->setAttribute('tempId',$tempId);<br/> $path=".//*[@auto and not(ancestor::*[@auto and ancestor::*[@tempId='$tempId']])]";<br/> $ar=$this->getElementsByXPath($path);<br/> $this->removeAttribute('tempId');<br/> </code> <br/> But I found the query is slowly, maybe .. , because the query is too complex?, And is there a way that do a better job?</p> <p><strong>I'v write a testing, plz have a look:</strong></p> <pre> &lt;?php $xml=' &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; '; $doc=new DomDocument(); $tempId='XDFAY69LA'; $doc-&gt;loadXml($xml); $domxpath=new DOMXPath($doc); $a=$domxpath-&gt;query('a')-&gt;item(0); $path=".//*[@auto and not(ancestor::*[@auto and ancestor::*[@tempId='$tempId']])]"; $start=microtime(true); for($n=0;$n&lt;1000;$n++){ //run 1000 times $a-&gt;setAttribute('tempId',$tempId); $ar=$domxpath-&gt;query($path,$a); $a-&gt;removeAttribute('tempId'); for($i=0;$i&lt;$ar-&gt;length;$i++){ $node=$ar-&gt;item($i); //echo $node-&gt;tagName . "\n"; } } $cost=round(1000 * (microtime(true)-$start)); echo "time cost: $cost"; ?&gt; </pre>
 

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