File: C:/Ruby27-x64/share/doc/ruby/html/REXML/XPathParser.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>class REXML::XPathParser - RDoc Documentation</title>
<script type="text/javascript">
var rdoc_rel_prefix = "../";
var index_rel_prefix = "../";
</script>
<script src="../js/navigation.js" defer></script>
<script src="../js/search.js" defer></script>
<script src="../js/search_index.js" defer></script>
<script src="../js/searcher.js" defer></script>
<script src="../js/darkfish.js" defer></script>
<link href="../css/fonts.css" rel="stylesheet">
<link href="../css/rdoc.css" rel="stylesheet">
<body id="top" role="document" class="class">
<nav role="navigation">
<div id="project-navigation">
<div id="home-section" role="region" title="Quick navigation" class="nav-section">
<h2>
<a href="../index.html" rel="home">Home</a>
</h2>
<div id="table-of-contents-navigation">
<a href="../table_of_contents.html#pages">Pages</a>
<a href="../table_of_contents.html#classes">Classes</a>
<a href="../table_of_contents.html#methods">Methods</a>
</div>
</div>
<div id="search-section" role="search" class="project-section initially-hidden">
<form action="#" method="get" accept-charset="utf-8">
<div id="search-field-wrapper">
<input id="search-field" role="combobox" aria-label="Search"
aria-autocomplete="list" aria-controls="search-results"
type="text" name="search" placeholder="Search" spellcheck="false"
title="Type to search, Up and Down to navigate, Enter to load">
</div>
<ul id="search-results" aria-label="Search Results"
aria-busy="false" aria-expanded="false"
aria-atomic="false" class="initially-hidden"></ul>
</form>
</div>
</div>
<div id="class-metadata">
<div id="parent-class-section" class="nav-section">
<h3>Parent</h3>
<p class="link"><a href="../Object.html">Object</a>
</div>
<div id="includes-section" class="nav-section">
<h3>Included Modules</h3>
<ul class="link-list">
<li><a class="include" href="XMLTokens.html">REXML::XMLTokens</a>
</ul>
</div>
<!-- Method Quickref -->
<div id="method-list-section" class="nav-section">
<h3>Methods</h3>
<ul class="link-list" role="directory">
<li ><a href="#method-c-new">::new</a>
<li ><a href="#method-i-5B-5D-3D">#[]=</a>
<li ><a href="#method-i-child">#child</a>
<li ><a href="#method-i-compare">#compare</a>
<li ><a href="#method-i-descendant">#descendant</a>
<li ><a href="#method-i-descendant_recursive">#descendant_recursive</a>
<li ><a href="#method-i-each_unnode">#each_unnode</a>
<li ><a href="#method-i-enter">#enter</a>
<li ><a href="#method-i-equality_relational_compare">#equality_relational_compare</a>
<li ><a href="#method-i-evaluate_predicate">#evaluate_predicate</a>
<li ><a href="#method-i-expr">#expr</a>
<li ><a href="#method-i-filter_nodeset">#filter_nodeset</a>
<li ><a href="#method-i-first">#first</a>
<li ><a href="#method-i-following">#following</a>
<li ><a href="#method-i-following_node_of">#following_node_of</a>
<li ><a href="#method-i-get_first">#get_first</a>
<li ><a href="#method-i-get_namespace">#get_namespace</a>
<li ><a href="#method-i-leave">#leave</a>
<li ><a href="#method-i-match">#match</a>
<li ><a href="#method-i-namespaces-3D">#namespaces=</a>
<li ><a href="#method-i-next_sibling_node">#next_sibling_node</a>
<li ><a href="#method-i-node_test">#node_test</a>
<li ><a href="#method-i-norm">#norm</a>
<li ><a href="#method-i-normalize_compare_values">#normalize_compare_values</a>
<li ><a href="#method-i-parse">#parse</a>
<li ><a href="#method-i-preceding">#preceding</a>
<li ><a href="#method-i-preceding_node_of">#preceding_node_of</a>
<li ><a href="#method-i-predicate">#predicate</a>
<li ><a href="#method-i-sort">#sort</a>
<li ><a href="#method-i-step">#step</a>
<li ><a href="#method-i-strict-3F">#strict?</a>
<li ><a href="#method-i-trace">#trace</a>
<li ><a href="#method-i-unnode">#unnode</a>
<li ><a href="#method-i-value_type">#value_type</a>
<li ><a href="#method-i-variables-3D">#variables=</a>
</ul>
</div>
</div>
</nav>
<main role="main" aria-labelledby="class-REXML::XPathParser">
<h1 id="class-REXML::XPathParser" class="class">
class REXML::XPathParser
</h1>
<section class="description">
<p>You don't want to use this class. Really. Use <a href="XPath.html"><code>XPath</code></a>, which is a wrapper for this class. Believe me. You don't want to poke around in here. There is strange, dark magic at work in this code. Beware. Go back! Go back while you still can!</p>
</section>
<section id="5Buntitled-5D" class="documentation-section">
<section class="constants-list">
<header>
<h3>Constants</h3>
</header>
<dl>
<dt id="DEBUG">DEBUG
<dd>
<dt id="LITERAL">LITERAL
<dd>
</dl>
</section>
<section id="public-class-5Buntitled-5D-method-details" class="method-section">
<header>
<h3>Public Class Methods</h3>
</header>
<div id="method-c-new" class="method-detail ">
<div class="method-heading">
<span class="method-name">new</span><span
class="method-args">(strict: false)</span>
<span class="method-click-advice">click to toggle source</span>
</div>
<div class="method-description">
<div class="method-source-code" id="new-source">
<pre><span class="ruby-comment"># File lib/rexml/xpath_parser.rb, line 54</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">initialize</span>(<span class="ruby-value">strict:</span> <span class="ruby-keyword">false</span>)
<span class="ruby-ivar">@debug</span> = <span class="ruby-constant">DEBUG</span>
<span class="ruby-ivar">@parser</span> = <span class="ruby-constant">REXML</span><span class="ruby-operator">::</span><span class="ruby-constant">Parsers</span><span class="ruby-operator">::</span><span class="ruby-constant">XPathParser</span>.<span class="ruby-identifier">new</span>
<span class="ruby-ivar">@namespaces</span> = <span class="ruby-keyword">nil</span>
<span class="ruby-ivar">@variables</span> = {}
<span class="ruby-ivar">@nest</span> = <span class="ruby-value">0</span>
<span class="ruby-ivar">@strict</span> = <span class="ruby-identifier">strict</span>
<span class="ruby-keyword">end</span></pre>
</div>
</div>
</div>
</section>
<section id="public-instance-5Buntitled-5D-method-details" class="method-section">
<header>
<h3>Public Instance Methods</h3>
</header>
<div id="method-i-5B-5D-3D" class="method-detail ">
<div class="method-heading">
<span class="method-name">[]=</span><span
class="method-args">( variable_name, value )</span>
<span class="method-click-advice">click to toggle source</span>
</div>
<div class="method-description">
<div class="method-source-code" id="5B-5D-3D-source">
<pre><span class="ruby-comment"># File lib/rexml/xpath_parser.rb, line 88</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">[]=</span>( <span class="ruby-identifier">variable_name</span>, <span class="ruby-identifier">value</span> )
<span class="ruby-ivar">@variables</span>[ <span class="ruby-identifier">variable_name</span> ] = <span class="ruby-identifier">value</span>
<span class="ruby-keyword">end</span></pre>
</div>
</div>
</div>
<div id="method-i-first" class="method-detail ">
<div class="method-heading">
<span class="method-name">first</span><span
class="method-args">( path_stack, node )</span>
<span class="method-click-advice">click to toggle source</span>
</div>
<div class="method-description">
<p>Performs a depth-first (document order) <a href="XPath.html"><code>XPath</code></a> search, and returns the first match. This is the fastest, lightest way to return a single result.</p>
<p>FIXME: This method is incomplete!</p>
<div class="method-source-code" id="first-source">
<pre><span class="ruby-comment"># File lib/rexml/xpath_parser.rb, line 97</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">first</span>( <span class="ruby-identifier">path_stack</span>, <span class="ruby-identifier">node</span> )
<span class="ruby-keyword">return</span> <span class="ruby-keyword">nil</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">path</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">==</span> <span class="ruby-value">0</span>
<span class="ruby-keyword">case</span> <span class="ruby-identifier">path</span>[<span class="ruby-value">0</span>]
<span class="ruby-keyword">when</span> <span class="ruby-value">:document</span>
<span class="ruby-comment"># do nothing</span>
<span class="ruby-keyword">return</span> <span class="ruby-identifier">first</span>( <span class="ruby-identifier">path</span>[<span class="ruby-value">1</span><span class="ruby-operator">..</span><span class="ruby-value">-1</span>], <span class="ruby-identifier">node</span> )
<span class="ruby-keyword">when</span> <span class="ruby-value">:child</span>
<span class="ruby-keyword">for</span> <span class="ruby-identifier">c</span> <span class="ruby-keyword">in</span> <span class="ruby-identifier">node</span>.<span class="ruby-identifier">children</span>
<span class="ruby-identifier">r</span> = <span class="ruby-identifier">first</span>( <span class="ruby-identifier">path</span>[<span class="ruby-value">1</span><span class="ruby-operator">..</span><span class="ruby-value">-1</span>], <span class="ruby-identifier">c</span> )
<span class="ruby-keyword">return</span> <span class="ruby-identifier">r</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">r</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">when</span> <span class="ruby-value">:qname</span>
<span class="ruby-identifier">name</span> = <span class="ruby-identifier">path</span>[<span class="ruby-value">2</span>]
<span class="ruby-keyword">if</span> <span class="ruby-identifier">node</span>.<span class="ruby-identifier">name</span> <span class="ruby-operator">==</span> <span class="ruby-identifier">name</span>
<span class="ruby-keyword">return</span> <span class="ruby-identifier">node</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">path</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">==</span> <span class="ruby-value">3</span>
<span class="ruby-keyword">return</span> <span class="ruby-identifier">first</span>( <span class="ruby-identifier">path</span>[<span class="ruby-value">3</span><span class="ruby-operator">..</span><span class="ruby-value">-1</span>], <span class="ruby-identifier">node</span> )
<span class="ruby-keyword">else</span>
<span class="ruby-keyword">return</span> <span class="ruby-keyword">nil</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">when</span> <span class="ruby-value">:descendant_or_self</span>
<span class="ruby-identifier">r</span> = <span class="ruby-identifier">first</span>( <span class="ruby-identifier">path</span>[<span class="ruby-value">1</span><span class="ruby-operator">..</span><span class="ruby-value">-1</span>], <span class="ruby-identifier">node</span> )
<span class="ruby-keyword">return</span> <span class="ruby-identifier">r</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">r</span>
<span class="ruby-keyword">for</span> <span class="ruby-identifier">c</span> <span class="ruby-keyword">in</span> <span class="ruby-identifier">node</span>.<span class="ruby-identifier">children</span>
<span class="ruby-identifier">r</span> = <span class="ruby-identifier">first</span>( <span class="ruby-identifier">path</span>, <span class="ruby-identifier">c</span> )
<span class="ruby-keyword">return</span> <span class="ruby-identifier">r</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">r</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">when</span> <span class="ruby-value">:node</span>
<span class="ruby-keyword">return</span> <span class="ruby-identifier">first</span>( <span class="ruby-identifier">path</span>[<span class="ruby-value">1</span><span class="ruby-operator">..</span><span class="ruby-value">-1</span>], <span class="ruby-identifier">node</span> )
<span class="ruby-keyword">when</span> <span class="ruby-value">:any</span>
<span class="ruby-keyword">return</span> <span class="ruby-identifier">first</span>( <span class="ruby-identifier">path</span>[<span class="ruby-value">1</span><span class="ruby-operator">..</span><span class="ruby-value">-1</span>], <span class="ruby-identifier">node</span> )
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">return</span> <span class="ruby-keyword">nil</span>
<span class="ruby-keyword">end</span></pre>
</div>
</div>
</div>
<div id="method-i-get_first" class="method-detail ">
<div class="method-heading">
<span class="method-name">get_first</span><span
class="method-args">(path, nodeset)</span>
<span class="method-click-advice">click to toggle source</span>
</div>
<div class="method-description">
<div class="method-source-code" id="get_first-source">
<pre><span class="ruby-comment"># File lib/rexml/xpath_parser.rb, line 78</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">get_first</span> <span class="ruby-identifier">path</span>, <span class="ruby-identifier">nodeset</span>
<span class="ruby-identifier">path_stack</span> = <span class="ruby-ivar">@parser</span>.<span class="ruby-identifier">parse</span>( <span class="ruby-identifier">path</span> )
<span class="ruby-identifier">first</span>( <span class="ruby-identifier">path_stack</span>, <span class="ruby-identifier">nodeset</span> )
<span class="ruby-keyword">end</span></pre>
</div>
</div>
</div>
<div id="method-i-match" class="method-detail ">
<div class="method-heading">
<span class="method-name">match</span><span
class="method-args">(path_stack, nodeset)</span>
<span class="method-click-advice">click to toggle source</span>
</div>
<div class="method-description">
<div class="method-source-code" id="match-source">
<pre><span class="ruby-comment"># File lib/rexml/xpath_parser.rb, line 133</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">match</span>(<span class="ruby-identifier">path_stack</span>, <span class="ruby-identifier">nodeset</span>)
<span class="ruby-identifier">nodeset</span> = <span class="ruby-identifier">nodeset</span>.<span class="ruby-identifier">collect</span>.<span class="ruby-identifier">with_index</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">node</span>, <span class="ruby-identifier">i</span><span class="ruby-operator">|</span>
<span class="ruby-identifier">position</span> = <span class="ruby-identifier">i</span> <span class="ruby-operator">+</span> <span class="ruby-value">1</span>
<span class="ruby-constant">XPathNode</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">node</span>, <span class="ruby-value">position:</span> <span class="ruby-identifier">position</span>)
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">result</span> = <span class="ruby-identifier">expr</span>(<span class="ruby-identifier">path_stack</span>, <span class="ruby-identifier">nodeset</span>)
<span class="ruby-keyword">case</span> <span class="ruby-identifier">result</span>
<span class="ruby-keyword">when</span> <span class="ruby-constant">Array</span> <span class="ruby-comment"># nodeset</span>
<span class="ruby-identifier">unnode</span>(<span class="ruby-identifier">result</span>)
<span class="ruby-keyword">else</span>
[<span class="ruby-identifier">result</span>]
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span></pre>
</div>
</div>
</div>
<div id="method-i-namespaces-3D" class="method-detail ">
<div class="method-heading">
<span class="method-name">namespaces=</span><span
class="method-args">( namespaces={} )</span>
<span class="method-click-advice">click to toggle source</span>
</div>
<div class="method-description">
<div class="method-source-code" id="namespaces-3D-source">
<pre><span class="ruby-comment"># File lib/rexml/xpath_parser.rb, line 63</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">namespaces=</span>( <span class="ruby-identifier">namespaces</span>={} )
<span class="ruby-constant">Functions</span><span class="ruby-operator">::</span><span class="ruby-identifier">namespace_context</span> = <span class="ruby-identifier">namespaces</span>
<span class="ruby-ivar">@namespaces</span> = <span class="ruby-identifier">namespaces</span>
<span class="ruby-keyword">end</span></pre>
</div>
</div>
</div>
<div id="method-i-parse" class="method-detail ">
<div class="method-heading">
<span class="method-name">parse</span><span
class="method-args">(path, nodeset)</span>
<span class="method-click-advice">click to toggle source</span>
</div>
<div class="method-description">
<div class="method-source-code" id="parse-source">
<pre><span class="ruby-comment"># File lib/rexml/xpath_parser.rb, line 73</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">parse</span> <span class="ruby-identifier">path</span>, <span class="ruby-identifier">nodeset</span>
<span class="ruby-identifier">path_stack</span> = <span class="ruby-ivar">@parser</span>.<span class="ruby-identifier">parse</span>( <span class="ruby-identifier">path</span> )
<span class="ruby-identifier">match</span>( <span class="ruby-identifier">path_stack</span>, <span class="ruby-identifier">nodeset</span> )
<span class="ruby-keyword">end</span></pre>
</div>
</div>
</div>
<div id="method-i-predicate" class="method-detail ">
<div class="method-heading">
<span class="method-name">predicate</span><span
class="method-args">(path, nodeset)</span>
<span class="method-click-advice">click to toggle source</span>
</div>
<div class="method-description">
<div class="method-source-code" id="predicate-source">
<pre><span class="ruby-comment"># File lib/rexml/xpath_parser.rb, line 83</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">predicate</span> <span class="ruby-identifier">path</span>, <span class="ruby-identifier">nodeset</span>
<span class="ruby-identifier">path_stack</span> = <span class="ruby-ivar">@parser</span>.<span class="ruby-identifier">parse</span>( <span class="ruby-identifier">path</span> )
<span class="ruby-identifier">match</span>( <span class="ruby-identifier">path_stack</span>, <span class="ruby-identifier">nodeset</span> )
<span class="ruby-keyword">end</span></pre>
</div>
</div>
</div>
<div id="method-i-variables-3D" class="method-detail ">
<div class="method-heading">
<span class="method-name">variables=</span><span
class="method-args">( vars={} )</span>
<span class="method-click-advice">click to toggle source</span>
</div>
<div class="method-description">
<div class="method-source-code" id="variables-3D-source">
<pre><span class="ruby-comment"># File lib/rexml/xpath_parser.rb, line 68</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">variables=</span>( <span class="ruby-identifier">vars</span>={} )
<span class="ruby-constant">Functions</span><span class="ruby-operator">::</span><span class="ruby-identifier">variables</span> = <span class="ruby-identifier">vars</span>
<span class="ruby-ivar">@variables</span> = <span class="ruby-identifier">vars</span>
<span class="ruby-keyword">end</span></pre>
</div>
</div>
</div>
</section>
<section id="private-instance-5Buntitled-5D-method-details" class="method-section">
<header>
<h3>Private Instance Methods</h3>
</header>
<div id="method-i-child" class="method-detail ">
<div class="method-heading">
<span class="method-name">child</span><span
class="method-args">(nodeset)</span>
<span class="method-click-advice">click to toggle source</span>
</div>
<div class="method-description">
<div class="method-source-code" id="child-source">
<pre><span class="ruby-comment"># File lib/rexml/xpath_parser.rb, line 769</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">child</span>(<span class="ruby-identifier">nodeset</span>)
<span class="ruby-identifier">nodesets</span> = []
<span class="ruby-identifier">nodeset</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">node</span><span class="ruby-operator">|</span>
<span class="ruby-identifier">raw_node</span> = <span class="ruby-identifier">node</span>.<span class="ruby-identifier">raw_node</span>
<span class="ruby-identifier">node_type</span> = <span class="ruby-identifier">raw_node</span>.<span class="ruby-identifier">node_type</span>
<span class="ruby-comment"># trace(:child, node_type, node)</span>
<span class="ruby-keyword">case</span> <span class="ruby-identifier">node_type</span>
<span class="ruby-keyword">when</span> <span class="ruby-value">:element</span>
<span class="ruby-identifier">nodesets</span> <span class="ruby-operator"><<</span> <span class="ruby-identifier">raw_node</span>.<span class="ruby-identifier">children</span>.<span class="ruby-identifier">collect</span>.<span class="ruby-identifier">with_index</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">child_node</span>, <span class="ruby-identifier">i</span><span class="ruby-operator">|</span>
<span class="ruby-constant">XPathNode</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">child_node</span>, <span class="ruby-value">position:</span> <span class="ruby-identifier">i</span> <span class="ruby-operator">+</span> <span class="ruby-value">1</span>)
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">when</span> <span class="ruby-value">:document</span>
<span class="ruby-identifier">new_nodeset</span> = []
<span class="ruby-identifier">raw_node</span>.<span class="ruby-identifier">children</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">child</span><span class="ruby-operator">|</span>
<span class="ruby-keyword">case</span> <span class="ruby-identifier">child</span>
<span class="ruby-keyword">when</span> <span class="ruby-constant">XMLDecl</span>, <span class="ruby-constant">Text</span>
<span class="ruby-comment"># Ignore</span>
<span class="ruby-keyword">else</span>
<span class="ruby-identifier">new_nodeset</span> <span class="ruby-operator"><<</span> <span class="ruby-constant">XPathNode</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">child</span>, <span class="ruby-value">position:</span> <span class="ruby-identifier">new_nodeset</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">+</span> <span class="ruby-value">1</span>)
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">nodesets</span> <span class="ruby-operator"><<</span> <span class="ruby-identifier">new_nodeset</span> <span class="ruby-keyword">unless</span> <span class="ruby-identifier">new_nodeset</span>.<span class="ruby-identifier">empty?</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">nodesets</span>
<span class="ruby-keyword">end</span></pre>
</div>
</div>
</div>
<div id="method-i-compare" class="method-detail ">
<div class="method-heading">
<span class="method-name">compare</span><span
class="method-args">(a, operator, b)</span>
<span class="method-click-advice">click to toggle source</span>
</div>
<div class="method-description">
<div class="method-source-code" id="compare-source">
<pre><span class="ruby-comment"># File lib/rexml/xpath_parser.rb, line 910</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">compare</span>(<span class="ruby-identifier">a</span>, <span class="ruby-identifier">operator</span>, <span class="ruby-identifier">b</span>)
<span class="ruby-identifier">a</span>, <span class="ruby-identifier">b</span> = <span class="ruby-identifier">normalize_compare_values</span>(<span class="ruby-identifier">a</span>, <span class="ruby-identifier">operator</span>, <span class="ruby-identifier">b</span>)
<span class="ruby-keyword">case</span> <span class="ruby-identifier">operator</span>
<span class="ruby-keyword">when</span> <span class="ruby-value">:eq</span>
<span class="ruby-identifier">a</span> <span class="ruby-operator">==</span> <span class="ruby-identifier">b</span>
<span class="ruby-keyword">when</span> <span class="ruby-value">:neq</span>
<span class="ruby-identifier">a</span> <span class="ruby-operator">!=</span> <span class="ruby-identifier">b</span>
<span class="ruby-keyword">when</span> <span class="ruby-value">:lt</span>
<span class="ruby-identifier">a</span> <span class="ruby-operator"><</span> <span class="ruby-identifier">b</span>
<span class="ruby-keyword">when</span> <span class="ruby-value">:lteq</span>
<span class="ruby-identifier">a</span> <span class="ruby-operator"><=</span> <span class="ruby-identifier">b</span>
<span class="ruby-keyword">when</span> <span class="ruby-value">:gt</span>
<span class="ruby-identifier">a</span> <span class="ruby-operator">></span> <span class="ruby-identifier">b</span>
<span class="ruby-keyword">when</span> <span class="ruby-value">:gteq</span>
<span class="ruby-identifier">a</span> <span class="ruby-operator">>=</span> <span class="ruby-identifier">b</span>
<span class="ruby-keyword">else</span>
<span class="ruby-identifier">message</span> = <span class="ruby-string">"[BUG] Unexpected compare operator: "</span> <span class="ruby-operator">+</span>
<span class="ruby-node">"<#{operator.inspect}>: <#{a.inspect}>: <#{b.inspect}>"</span>
<span class="ruby-identifier">raise</span> <span class="ruby-identifier">message</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span></pre>
</div>
</div>
</div>
<div id="method-i-descendant" class="method-detail ">
<div class="method-heading">
<span class="method-name">descendant</span><span
class="method-args">(nodeset, include_self)</span>
<span class="method-click-advice">click to toggle source</span>
</div>
<div class="method-description">
<div class="method-source-code" id="descendant-source">
<pre><span class="ruby-comment"># File lib/rexml/xpath_parser.rb, line 672</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">descendant</span>(<span class="ruby-identifier">nodeset</span>, <span class="ruby-identifier">include_self</span>)
<span class="ruby-identifier">nodesets</span> = []
<span class="ruby-identifier">nodeset</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">node</span><span class="ruby-operator">|</span>
<span class="ruby-identifier">new_nodeset</span> = []
<span class="ruby-identifier">new_nodes</span> = {}
<span class="ruby-identifier">descendant_recursive</span>(<span class="ruby-identifier">node</span>.<span class="ruby-identifier">raw_node</span>, <span class="ruby-identifier">new_nodeset</span>, <span class="ruby-identifier">new_nodes</span>, <span class="ruby-identifier">include_self</span>)
<span class="ruby-identifier">nodesets</span> <span class="ruby-operator"><<</span> <span class="ruby-identifier">new_nodeset</span> <span class="ruby-keyword">unless</span> <span class="ruby-identifier">new_nodeset</span>.<span class="ruby-identifier">empty?</span>
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">nodesets</span>
<span class="ruby-keyword">end</span></pre>
</div>
</div>
</div>
<div id="method-i-descendant_recursive" class="method-detail ">
<div class="method-heading">
<span class="method-name">descendant_recursive</span><span
class="method-args">(raw_node, new_nodeset, new_nodes, include_self)</span>
<span class="method-click-advice">click to toggle source</span>
</div>
<div class="method-description">
<div class="method-source-code" id="descendant_recursive-source">
<pre><span class="ruby-comment"># File lib/rexml/xpath_parser.rb, line 683</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">descendant_recursive</span>(<span class="ruby-identifier">raw_node</span>, <span class="ruby-identifier">new_nodeset</span>, <span class="ruby-identifier">new_nodes</span>, <span class="ruby-identifier">include_self</span>)
<span class="ruby-keyword">if</span> <span class="ruby-identifier">include_self</span>
<span class="ruby-keyword">return</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">new_nodes</span>.<span class="ruby-identifier">key?</span>(<span class="ruby-identifier">raw_node</span>)
<span class="ruby-identifier">new_nodeset</span> <span class="ruby-operator"><<</span> <span class="ruby-constant">XPathNode</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">raw_node</span>, <span class="ruby-value">position:</span> <span class="ruby-identifier">new_nodeset</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">+</span> <span class="ruby-value">1</span>)
<span class="ruby-identifier">new_nodes</span>[<span class="ruby-identifier">raw_node</span>] = <span class="ruby-keyword">true</span>
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">node_type</span> = <span class="ruby-identifier">raw_node</span>.<span class="ruby-identifier">node_type</span>
<span class="ruby-keyword">if</span> <span class="ruby-identifier">node_type</span> <span class="ruby-operator">==</span> <span class="ruby-value">:element</span> <span class="ruby-keyword">or</span> <span class="ruby-identifier">node_type</span> <span class="ruby-operator">==</span> <span class="ruby-value">:document</span>
<span class="ruby-identifier">raw_node</span>.<span class="ruby-identifier">children</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">child</span><span class="ruby-operator">|</span>
<span class="ruby-identifier">descendant_recursive</span>(<span class="ruby-identifier">child</span>, <span class="ruby-identifier">new_nodeset</span>, <span class="ruby-identifier">new_nodes</span>, <span class="ruby-keyword">true</span>)
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span></pre>
</div>
</div>
</div>
<div id="method-i-each_unnode" class="method-detail ">
<div class="method-heading">
<span class="method-name">each_unnode</span><span
class="method-args">(nodeset) { |unnoded| ... }</span>
<span class="method-click-advice">click to toggle source</span>
</div>
<div class="method-description">
<div class="method-source-code" id="each_unnode-source">
<pre><span class="ruby-comment"># File lib/rexml/xpath_parser.rb, line 932</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">each_unnode</span>(<span class="ruby-identifier">nodeset</span>)
<span class="ruby-keyword">return</span> <span class="ruby-identifier">to_enum</span>(<span class="ruby-identifier">__method__</span>, <span class="ruby-identifier">nodeset</span>) <span class="ruby-keyword">unless</span> <span class="ruby-identifier">block_given?</span>
<span class="ruby-identifier">nodeset</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">node</span><span class="ruby-operator">|</span>
<span class="ruby-keyword">if</span> <span class="ruby-identifier">node</span>.<span class="ruby-identifier">is_a?</span>(<span class="ruby-constant">XPathNode</span>)
<span class="ruby-identifier">unnoded</span> = <span class="ruby-identifier">node</span>.<span class="ruby-identifier">raw_node</span>
<span class="ruby-keyword">else</span>
<span class="ruby-identifier">unnoded</span> = <span class="ruby-identifier">node</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">yield</span>(<span class="ruby-identifier">unnoded</span>)
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span></pre>
</div>
</div>
</div>
<div id="method-i-enter" class="method-detail ">
<div class="method-heading">
<span class="method-name">enter</span><span
class="method-args">(tag, *args)</span>
<span class="method-click-advice">click to toggle source</span>
</div>
<div class="method-description">
<div class="method-source-code" id="enter-source">
<pre><span class="ruby-comment"># File lib/rexml/xpath_parser.rb, line 631</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">enter</span>(<span class="ruby-identifier">tag</span>, <span class="ruby-operator">*</span><span class="ruby-identifier">args</span>)
<span class="ruby-identifier">trace</span>(<span class="ruby-value">:enter</span>, <span class="ruby-identifier">tag</span>, <span class="ruby-operator">*</span><span class="ruby-identifier">args</span>)
<span class="ruby-ivar">@nest</span> <span class="ruby-operator">+=</span> <span class="ruby-value">1</span>
<span class="ruby-keyword">end</span></pre>
</div>
</div>
</div>
<div id="method-i-equality_relational_compare" class="method-detail ">
<div class="method-heading">
<span class="method-name">equality_relational_compare</span><span
class="method-args">(set1, op, set2)</span>
<span class="method-click-advice">click to toggle source</span>
</div>
<div class="method-description">
<div class="method-source-code" id="equality_relational_compare-source">
<pre><span class="ruby-comment"># File lib/rexml/xpath_parser.rb, line 809</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">equality_relational_compare</span>(<span class="ruby-identifier">set1</span>, <span class="ruby-identifier">op</span>, <span class="ruby-identifier">set2</span>)
<span class="ruby-identifier">set1</span> = <span class="ruby-identifier">unnode</span>(<span class="ruby-identifier">set1</span>) <span class="ruby-keyword">if</span> <span class="ruby-identifier">set1</span>.<span class="ruby-identifier">is_a?</span>(<span class="ruby-constant">Array</span>)
<span class="ruby-identifier">set2</span> = <span class="ruby-identifier">unnode</span>(<span class="ruby-identifier">set2</span>) <span class="ruby-keyword">if</span> <span class="ruby-identifier">set2</span>.<span class="ruby-identifier">is_a?</span>(<span class="ruby-constant">Array</span>)
<span class="ruby-keyword">if</span> <span class="ruby-identifier">set1</span>.<span class="ruby-identifier">kind_of?</span> <span class="ruby-constant">Array</span> <span class="ruby-keyword">and</span> <span class="ruby-identifier">set2</span>.<span class="ruby-identifier">kind_of?</span> <span class="ruby-constant">Array</span>
<span class="ruby-comment"># If both objects to be compared are node-sets, then the</span>
<span class="ruby-comment"># comparison will be true if and only if there is a node in the</span>
<span class="ruby-comment"># first node-set and a node in the second node-set such that the</span>
<span class="ruby-comment"># result of performing the comparison on the string-values of</span>
<span class="ruby-comment"># the two nodes is true.</span>
<span class="ruby-identifier">set1</span>.<span class="ruby-identifier">product</span>(<span class="ruby-identifier">set2</span>).<span class="ruby-identifier">any?</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">node1</span>, <span class="ruby-identifier">node2</span><span class="ruby-operator">|</span>
<span class="ruby-identifier">node_string1</span> = <span class="ruby-constant">Functions</span>.<span class="ruby-identifier">string</span>(<span class="ruby-identifier">node1</span>)
<span class="ruby-identifier">node_string2</span> = <span class="ruby-constant">Functions</span>.<span class="ruby-identifier">string</span>(<span class="ruby-identifier">node2</span>)
<span class="ruby-identifier">compare</span>(<span class="ruby-identifier">node_string1</span>, <span class="ruby-identifier">op</span>, <span class="ruby-identifier">node_string2</span>)
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">elsif</span> <span class="ruby-identifier">set1</span>.<span class="ruby-identifier">kind_of?</span> <span class="ruby-constant">Array</span> <span class="ruby-keyword">or</span> <span class="ruby-identifier">set2</span>.<span class="ruby-identifier">kind_of?</span> <span class="ruby-constant">Array</span>
<span class="ruby-comment"># If one is nodeset and other is number, compare number to each item</span>
<span class="ruby-comment"># in nodeset s.t. number op number(string(item))</span>
<span class="ruby-comment"># If one is nodeset and other is string, compare string to each item</span>
<span class="ruby-comment"># in nodeset s.t. string op string(item)</span>
<span class="ruby-comment"># If one is nodeset and other is boolean, compare boolean to each item</span>
<span class="ruby-comment"># in nodeset s.t. boolean op boolean(item)</span>
<span class="ruby-keyword">if</span> <span class="ruby-identifier">set1</span>.<span class="ruby-identifier">kind_of?</span> <span class="ruby-constant">Array</span>
<span class="ruby-identifier">a</span> = <span class="ruby-identifier">set1</span>
<span class="ruby-identifier">b</span> = <span class="ruby-identifier">set2</span>
<span class="ruby-keyword">else</span>
<span class="ruby-identifier">a</span> = <span class="ruby-identifier">set2</span>
<span class="ruby-identifier">b</span> = <span class="ruby-identifier">set1</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">case</span> <span class="ruby-identifier">b</span>
<span class="ruby-keyword">when</span> <span class="ruby-keyword">true</span>, <span class="ruby-keyword">false</span>
<span class="ruby-identifier">each_unnode</span>(<span class="ruby-identifier">a</span>).<span class="ruby-identifier">any?</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">unnoded</span><span class="ruby-operator">|</span>
<span class="ruby-identifier">compare</span>(<span class="ruby-constant">Functions</span>.<span class="ruby-identifier">boolean</span>(<span class="ruby-identifier">unnoded</span>), <span class="ruby-identifier">op</span>, <span class="ruby-identifier">b</span>)
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">when</span> <span class="ruby-constant">Numeric</span>
<span class="ruby-identifier">each_unnode</span>(<span class="ruby-identifier">a</span>).<span class="ruby-identifier">any?</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">unnoded</span><span class="ruby-operator">|</span>
<span class="ruby-identifier">compare</span>(<span class="ruby-constant">Functions</span>.<span class="ruby-identifier">number</span>(<span class="ruby-identifier">unnoded</span>), <span class="ruby-identifier">op</span>, <span class="ruby-identifier">b</span>)
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">when</span> <span class="ruby-regexp">/\A\d+(\.\d+)?\z/</span>
<span class="ruby-identifier">b</span> = <span class="ruby-constant">Functions</span>.<span class="ruby-identifier">number</span>(<span class="ruby-identifier">b</span>)
<span class="ruby-identifier">each_unnode</span>(<span class="ruby-identifier">a</span>).<span class="ruby-identifier">any?</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">unnoded</span><span class="ruby-operator">|</span>
<span class="ruby-identifier">compare</span>(<span class="ruby-constant">Functions</span>.<span class="ruby-identifier">number</span>(<span class="ruby-identifier">unnoded</span>), <span class="ruby-identifier">op</span>, <span class="ruby-identifier">b</span>)
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">else</span>
<span class="ruby-identifier">b</span> = <span class="ruby-constant">Functions</span><span class="ruby-operator">::</span><span class="ruby-identifier">string</span>(<span class="ruby-identifier">b</span>)
<span class="ruby-identifier">each_unnode</span>(<span class="ruby-identifier">a</span>).<span class="ruby-identifier">any?</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">unnoded</span><span class="ruby-operator">|</span>
<span class="ruby-identifier">compare</span>(<span class="ruby-constant">Functions</span><span class="ruby-operator">::</span><span class="ruby-identifier">string</span>(<span class="ruby-identifier">unnoded</span>), <span class="ruby-identifier">op</span>, <span class="ruby-identifier">b</span>)
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">else</span>
<span class="ruby-comment"># If neither is nodeset,</span>
<span class="ruby-comment"># If op is = or !=</span>
<span class="ruby-comment"># If either boolean, convert to boolean</span>
<span class="ruby-comment"># If either number, convert to number</span>
<span class="ruby-comment"># Else, convert to string</span>
<span class="ruby-comment"># Else</span>
<span class="ruby-comment"># Convert both to numbers and compare</span>
<span class="ruby-identifier">compare</span>(<span class="ruby-identifier">set1</span>, <span class="ruby-identifier">op</span>, <span class="ruby-identifier">set2</span>)
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span></pre>
</div>
</div>
</div>
<div id="method-i-evaluate_predicate" class="method-detail ">
<div class="method-heading">
<span class="method-name">evaluate_predicate</span><span
class="method-args">(expression, nodesets)</span>
<span class="method-click-advice">click to toggle source</span>
</div>
<div class="method-description">
<div class="method-source-code" id="evaluate_predicate-source">
<pre><span class="ruby-comment"># File lib/rexml/xpath_parser.rb, line 585</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">evaluate_predicate</span>(<span class="ruby-identifier">expression</span>, <span class="ruby-identifier">nodesets</span>)
<span class="ruby-identifier">enter</span>(<span class="ruby-value">:predicate</span>, <span class="ruby-identifier">expression</span>, <span class="ruby-identifier">nodesets</span>) <span class="ruby-keyword">if</span> <span class="ruby-ivar">@debug</span>
<span class="ruby-identifier">new_nodesets</span> = <span class="ruby-identifier">nodesets</span>.<span class="ruby-identifier">collect</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">nodeset</span><span class="ruby-operator">|</span>
<span class="ruby-identifier">new_nodeset</span> = []
<span class="ruby-identifier">subcontext</span> = { <span class="ruby-value">:size</span> <span class="ruby-operator">=></span> <span class="ruby-identifier">nodeset</span>.<span class="ruby-identifier">size</span> }
<span class="ruby-identifier">nodeset</span>.<span class="ruby-identifier">each_with_index</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">node</span>, <span class="ruby-identifier">index</span><span class="ruby-operator">|</span>
<span class="ruby-keyword">if</span> <span class="ruby-identifier">node</span>.<span class="ruby-identifier">is_a?</span>(<span class="ruby-constant">XPathNode</span>)
<span class="ruby-identifier">subcontext</span>[<span class="ruby-value">:node</span>] = <span class="ruby-identifier">node</span>.<span class="ruby-identifier">raw_node</span>
<span class="ruby-identifier">subcontext</span>[<span class="ruby-value">:index</span>] = <span class="ruby-identifier">node</span>.<span class="ruby-identifier">position</span>
<span class="ruby-keyword">else</span>
<span class="ruby-identifier">subcontext</span>[<span class="ruby-value">:node</span>] = <span class="ruby-identifier">node</span>
<span class="ruby-identifier">subcontext</span>[<span class="ruby-value">:index</span>] = <span class="ruby-identifier">index</span> <span class="ruby-operator">+</span> <span class="ruby-value">1</span>
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">result</span> = <span class="ruby-identifier">expr</span>(<span class="ruby-identifier">expression</span>.<span class="ruby-identifier">dclone</span>, [<span class="ruby-identifier">node</span>], <span class="ruby-identifier">subcontext</span>)
<span class="ruby-identifier">trace</span>(<span class="ruby-value">:predicate_evaluate</span>, <span class="ruby-identifier">expression</span>, <span class="ruby-identifier">node</span>, <span class="ruby-identifier">subcontext</span>, <span class="ruby-identifier">result</span>) <span class="ruby-keyword">if</span> <span class="ruby-ivar">@debug</span>
<span class="ruby-identifier">result</span> = <span class="ruby-identifier">result</span>[<span class="ruby-value">0</span>] <span class="ruby-keyword">if</span> <span class="ruby-identifier">result</span>.<span class="ruby-identifier">kind_of?</span> <span class="ruby-constant">Array</span> <span class="ruby-keyword">and</span> <span class="ruby-identifier">result</span>.<span class="ruby-identifier">length</span> <span class="ruby-operator">==</span> <span class="ruby-value">1</span>
<span class="ruby-keyword">if</span> <span class="ruby-identifier">result</span>.<span class="ruby-identifier">kind_of?</span> <span class="ruby-constant">Numeric</span>
<span class="ruby-keyword">if</span> <span class="ruby-identifier">result</span> <span class="ruby-operator">==</span> <span class="ruby-identifier">node</span>.<span class="ruby-identifier">position</span>
<span class="ruby-identifier">new_nodeset</span> <span class="ruby-operator"><<</span> <span class="ruby-constant">XPathNode</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">node</span>, <span class="ruby-value">position:</span> <span class="ruby-identifier">new_nodeset</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">+</span> <span class="ruby-value">1</span>)
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">elsif</span> <span class="ruby-identifier">result</span>.<span class="ruby-identifier">instance_of?</span> <span class="ruby-constant">Array</span>
<span class="ruby-keyword">if</span> <span class="ruby-identifier">result</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">></span> <span class="ruby-value">0</span> <span class="ruby-keyword">and</span> <span class="ruby-identifier">result</span>.<span class="ruby-identifier">inject</span>(<span class="ruby-keyword">false</span>) {<span class="ruby-operator">|</span><span class="ruby-identifier">k</span>,<span class="ruby-identifier">s</span><span class="ruby-operator">|</span> <span class="ruby-identifier">s</span> <span class="ruby-keyword">or</span> <span class="ruby-identifier">k</span>}
<span class="ruby-keyword">if</span> <span class="ruby-identifier">result</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">></span> <span class="ruby-value">0</span>
<span class="ruby-identifier">new_nodeset</span> <span class="ruby-operator"><<</span> <span class="ruby-constant">XPathNode</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">node</span>, <span class="ruby-value">position:</span> <span class="ruby-identifier">new_nodeset</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">+</span> <span class="ruby-value">1</span>)
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">else</span>
<span class="ruby-keyword">if</span> <span class="ruby-identifier">result</span>
<span class="ruby-identifier">new_nodeset</span> <span class="ruby-operator"><<</span> <span class="ruby-constant">XPathNode</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">node</span>, <span class="ruby-value">position:</span> <span class="ruby-identifier">new_nodeset</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">+</span> <span class="ruby-value">1</span>)
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">new_nodeset</span>
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">new_nodesets</span>
<span class="ruby-keyword">ensure</span>
<span class="ruby-identifier">leave</span>(<span class="ruby-value">:predicate</span>, <span class="ruby-identifier">new_nodesets</span>) <span class="ruby-keyword">if</span> <span class="ruby-ivar">@debug</span>
<span class="ruby-keyword">end</span></pre>
</div>
</div>
</div>
<div id="method-i-expr" class="method-detail ">
<div class="method-heading">
<span class="method-name">expr</span><span
class="method-args">( path_stack, nodeset, context=nil )</span>
<span class="method-click-advice">click to toggle source</span>
</div>
<div class="method-description">
<p>Expr takes a stack of path elements and a set of nodes (either a <a href="Parent.html"><code>Parent</code></a> or an <a href="../Array.html"><code>Array</code></a> and returns an <a href="../Array.html"><code>Array</code></a> of matching nodes</p>
<div class="method-source-code" id="expr-source">
<pre><span class="ruby-comment"># File lib/rexml/xpath_parser.rb, line 169</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">expr</span>( <span class="ruby-identifier">path_stack</span>, <span class="ruby-identifier">nodeset</span>, <span class="ruby-identifier">context</span>=<span class="ruby-keyword">nil</span> )
<span class="ruby-identifier">enter</span>(<span class="ruby-value">:expr</span>, <span class="ruby-identifier">path_stack</span>, <span class="ruby-identifier">nodeset</span>) <span class="ruby-keyword">if</span> <span class="ruby-ivar">@debug</span>
<span class="ruby-keyword">return</span> <span class="ruby-identifier">nodeset</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">path_stack</span>.<span class="ruby-identifier">length</span> <span class="ruby-operator">==</span> <span class="ruby-value">0</span> <span class="ruby-operator">||</span> <span class="ruby-identifier">nodeset</span>.<span class="ruby-identifier">length</span> <span class="ruby-operator">==</span> <span class="ruby-value">0</span>
<span class="ruby-keyword">while</span> <span class="ruby-identifier">path_stack</span>.<span class="ruby-identifier">length</span> <span class="ruby-operator">></span> <span class="ruby-value">0</span>
<span class="ruby-identifier">trace</span>(<span class="ruby-value">:while</span>, <span class="ruby-identifier">path_stack</span>, <span class="ruby-identifier">nodeset</span>) <span class="ruby-keyword">if</span> <span class="ruby-ivar">@debug</span>
<span class="ruby-keyword">if</span> <span class="ruby-identifier">nodeset</span>.<span class="ruby-identifier">length</span> <span class="ruby-operator">==</span> <span class="ruby-value">0</span>
<span class="ruby-identifier">path_stack</span>.<span class="ruby-identifier">clear</span>
<span class="ruby-keyword">return</span> []
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">op</span> = <span class="ruby-identifier">path_stack</span>.<span class="ruby-identifier">shift</span>
<span class="ruby-keyword">case</span> <span class="ruby-identifier">op</span>
<span class="ruby-keyword">when</span> <span class="ruby-value">:document</span>
<span class="ruby-identifier">first_raw_node</span> = <span class="ruby-identifier">nodeset</span>.<span class="ruby-identifier">first</span>.<span class="ruby-identifier">raw_node</span>
<span class="ruby-identifier">nodeset</span> = [<span class="ruby-constant">XPathNode</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">first_raw_node</span>.<span class="ruby-identifier">root_node</span>, <span class="ruby-value">position:</span> <span class="ruby-value">1</span>)]
<span class="ruby-keyword">when</span> <span class="ruby-value">:self</span>
<span class="ruby-identifier">nodeset</span> = <span class="ruby-identifier">step</span>(<span class="ruby-identifier">path_stack</span>) <span class="ruby-keyword">do</span>
[<span class="ruby-identifier">nodeset</span>]
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">when</span> <span class="ruby-value">:child</span>
<span class="ruby-identifier">nodeset</span> = <span class="ruby-identifier">step</span>(<span class="ruby-identifier">path_stack</span>) <span class="ruby-keyword">do</span>
<span class="ruby-identifier">child</span>(<span class="ruby-identifier">nodeset</span>)
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">when</span> <span class="ruby-value">:literal</span>
<span class="ruby-identifier">trace</span>(<span class="ruby-value">:literal</span>, <span class="ruby-identifier">path_stack</span>, <span class="ruby-identifier">nodeset</span>) <span class="ruby-keyword">if</span> <span class="ruby-ivar">@debug</span>
<span class="ruby-keyword">return</span> <span class="ruby-identifier">path_stack</span>.<span class="ruby-identifier">shift</span>
<span class="ruby-keyword">when</span> <span class="ruby-value">:attribute</span>
<span class="ruby-identifier">nodeset</span> = <span class="ruby-identifier">step</span>(<span class="ruby-identifier">path_stack</span>, <span class="ruby-value">any_type:</span> <span class="ruby-value">:attribute</span>) <span class="ruby-keyword">do</span>
<span class="ruby-identifier">nodesets</span> = []
<span class="ruby-identifier">nodeset</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">node</span><span class="ruby-operator">|</span>
<span class="ruby-identifier">raw_node</span> = <span class="ruby-identifier">node</span>.<span class="ruby-identifier">raw_node</span>
<span class="ruby-keyword">next</span> <span class="ruby-keyword">unless</span> <span class="ruby-identifier">raw_node</span>.<span class="ruby-identifier">node_type</span> <span class="ruby-operator">==</span> <span class="ruby-value">:element</span>
<span class="ruby-identifier">attributes</span> = <span class="ruby-identifier">raw_node</span>.<span class="ruby-identifier">attributes</span>
<span class="ruby-keyword">next</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">attributes</span>.<span class="ruby-identifier">empty?</span>
<span class="ruby-identifier">nodesets</span> <span class="ruby-operator"><<</span> <span class="ruby-identifier">attributes</span>.<span class="ruby-identifier">each_attribute</span>.<span class="ruby-identifier">collect</span>.<span class="ruby-identifier">with_index</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">attribute</span>, <span class="ruby-identifier">i</span><span class="ruby-operator">|</span>
<span class="ruby-constant">XPathNode</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">attribute</span>, <span class="ruby-value">position:</span> <span class="ruby-identifier">i</span> <span class="ruby-operator">+</span> <span class="ruby-value">1</span>)
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">nodesets</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">when</span> <span class="ruby-value">:namespace</span>
<span class="ruby-identifier">pre_defined_namespaces</span> = {
<span class="ruby-string">"xml"</span> <span class="ruby-operator">=></span> <span class="ruby-string">"http://www.w3.org/XML/1998/namespace"</span>,
}
<span class="ruby-identifier">nodeset</span> = <span class="ruby-identifier">step</span>(<span class="ruby-identifier">path_stack</span>, <span class="ruby-value">any_type:</span> <span class="ruby-value">:namespace</span>) <span class="ruby-keyword">do</span>
<span class="ruby-identifier">nodesets</span> = []
<span class="ruby-identifier">nodeset</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">node</span><span class="ruby-operator">|</span>
<span class="ruby-identifier">raw_node</span> = <span class="ruby-identifier">node</span>.<span class="ruby-identifier">raw_node</span>
<span class="ruby-keyword">case</span> <span class="ruby-identifier">raw_node</span>.<span class="ruby-identifier">node_type</span>
<span class="ruby-keyword">when</span> <span class="ruby-value">:element</span>
<span class="ruby-keyword">if</span> <span class="ruby-ivar">@namespaces</span>
<span class="ruby-identifier">nodesets</span> <span class="ruby-operator"><<</span> <span class="ruby-identifier">pre_defined_namespaces</span>.<span class="ruby-identifier">merge</span>(<span class="ruby-ivar">@namespaces</span>)
<span class="ruby-keyword">else</span>
<span class="ruby-identifier">nodesets</span> <span class="ruby-operator"><<</span> <span class="ruby-identifier">pre_defined_namespaces</span>.<span class="ruby-identifier">merge</span>(<span class="ruby-identifier">raw_node</span>.<span class="ruby-identifier">namespaces</span>)
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">when</span> <span class="ruby-value">:attribute</span>
<span class="ruby-keyword">if</span> <span class="ruby-ivar">@namespaces</span>
<span class="ruby-identifier">nodesets</span> <span class="ruby-operator"><<</span> <span class="ruby-identifier">pre_defined_namespaces</span>.<span class="ruby-identifier">merge</span>(<span class="ruby-ivar">@namespaces</span>)
<span class="ruby-keyword">else</span>
<span class="ruby-identifier">nodesets</span> <span class="ruby-operator"><<</span> <span class="ruby-identifier">pre_defined_namespaces</span>.<span class="ruby-identifier">merge</span>(<span class="ruby-identifier">raw_node</span>.<span class="ruby-identifier">element</span>.<span class="ruby-identifier">namespaces</span>)
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">nodesets</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">when</span> <span class="ruby-value">:parent</span>
<span class="ruby-identifier">nodeset</span> = <span class="ruby-identifier">step</span>(<span class="ruby-identifier">path_stack</span>) <span class="ruby-keyword">do</span>
<span class="ruby-identifier">nodesets</span> = []
<span class="ruby-identifier">nodeset</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">node</span><span class="ruby-operator">|</span>
<span class="ruby-identifier">raw_node</span> = <span class="ruby-identifier">node</span>.<span class="ruby-identifier">raw_node</span>
<span class="ruby-keyword">if</span> <span class="ruby-identifier">raw_node</span>.<span class="ruby-identifier">node_type</span> <span class="ruby-operator">==</span> <span class="ruby-value">:attribute</span>
<span class="ruby-identifier">parent</span> = <span class="ruby-identifier">raw_node</span>.<span class="ruby-identifier">element</span>
<span class="ruby-keyword">else</span>
<span class="ruby-identifier">parent</span> = <span class="ruby-identifier">raw_node</span>.<span class="ruby-identifier">parent</span>
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">nodesets</span> <span class="ruby-operator"><<</span> [<span class="ruby-constant">XPathNode</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">parent</span>, <span class="ruby-value">position:</span> <span class="ruby-value">1</span>)] <span class="ruby-keyword">if</span> <span class="ruby-identifier">parent</span>
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">nodesets</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">when</span> <span class="ruby-value">:ancestor</span>
<span class="ruby-identifier">nodeset</span> = <span class="ruby-identifier">step</span>(<span class="ruby-identifier">path_stack</span>) <span class="ruby-keyword">do</span>
<span class="ruby-identifier">nodesets</span> = []
<span class="ruby-comment"># new_nodes = {}</span>
<span class="ruby-identifier">nodeset</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">node</span><span class="ruby-operator">|</span>
<span class="ruby-identifier">raw_node</span> = <span class="ruby-identifier">node</span>.<span class="ruby-identifier">raw_node</span>
<span class="ruby-identifier">new_nodeset</span> = []
<span class="ruby-keyword">while</span> <span class="ruby-identifier">raw_node</span>.<span class="ruby-identifier">parent</span>
<span class="ruby-identifier">raw_node</span> = <span class="ruby-identifier">raw_node</span>.<span class="ruby-identifier">parent</span>
<span class="ruby-comment"># next if new_nodes.key?(node)</span>
<span class="ruby-identifier">new_nodeset</span> <span class="ruby-operator"><<</span> <span class="ruby-constant">XPathNode</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">raw_node</span>,
<span class="ruby-value">position:</span> <span class="ruby-identifier">new_nodeset</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">+</span> <span class="ruby-value">1</span>)
<span class="ruby-comment"># new_nodes[node] = true</span>
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">nodesets</span> <span class="ruby-operator"><<</span> <span class="ruby-identifier">new_nodeset</span> <span class="ruby-keyword">unless</span> <span class="ruby-identifier">new_nodeset</span>.<span class="ruby-identifier">empty?</span>
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">nodesets</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">when</span> <span class="ruby-value">:ancestor_or_self</span>
<span class="ruby-identifier">nodeset</span> = <span class="ruby-identifier">step</span>(<span class="ruby-identifier">path_stack</span>) <span class="ruby-keyword">do</span>
<span class="ruby-identifier">nodesets</span> = []
<span class="ruby-comment"># new_nodes = {}</span>
<span class="ruby-identifier">nodeset</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">node</span><span class="ruby-operator">|</span>
<span class="ruby-identifier">raw_node</span> = <span class="ruby-identifier">node</span>.<span class="ruby-identifier">raw_node</span>
<span class="ruby-keyword">next</span> <span class="ruby-keyword">unless</span> <span class="ruby-identifier">raw_node</span>.<span class="ruby-identifier">node_type</span> <span class="ruby-operator">==</span> <span class="ruby-value">:element</span>
<span class="ruby-identifier">new_nodeset</span> = [<span class="ruby-constant">XPathNode</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">raw_node</span>, <span class="ruby-value">position:</span> <span class="ruby-value">1</span>)]
<span class="ruby-comment"># new_nodes[node] = true</span>
<span class="ruby-keyword">while</span> <span class="ruby-identifier">raw_node</span>.<span class="ruby-identifier">parent</span>
<span class="ruby-identifier">raw_node</span> = <span class="ruby-identifier">raw_node</span>.<span class="ruby-identifier">parent</span>
<span class="ruby-comment"># next if new_nodes.key?(node)</span>
<span class="ruby-identifier">new_nodeset</span> <span class="ruby-operator"><<</span> <span class="ruby-constant">XPathNode</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">raw_node</span>,
<span class="ruby-value">position:</span> <span class="ruby-identifier">new_nodeset</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">+</span> <span class="ruby-value">1</span>)
<span class="ruby-comment"># new_nodes[node] = true</span>
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">nodesets</span> <span class="ruby-operator"><<</span> <span class="ruby-identifier">new_nodeset</span> <span class="ruby-keyword">unless</span> <span class="ruby-identifier">new_nodeset</span>.<span class="ruby-identifier">empty?</span>
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">nodesets</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">when</span> <span class="ruby-value">:descendant_or_self</span>
<span class="ruby-identifier">nodeset</span> = <span class="ruby-identifier">step</span>(<span class="ruby-identifier">path_stack</span>) <span class="ruby-keyword">do</span>
<span class="ruby-identifier">descendant</span>(<span class="ruby-identifier">nodeset</span>, <span class="ruby-keyword">true</span>)
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">when</span> <span class="ruby-value">:descendant</span>
<span class="ruby-identifier">nodeset</span> = <span class="ruby-identifier">step</span>(<span class="ruby-identifier">path_stack</span>) <span class="ruby-keyword">do</span>
<span class="ruby-identifier">descendant</span>(<span class="ruby-identifier">nodeset</span>, <span class="ruby-keyword">false</span>)
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">when</span> <span class="ruby-value">:following_sibling</span>
<span class="ruby-identifier">nodeset</span> = <span class="ruby-identifier">step</span>(<span class="ruby-identifier">path_stack</span>) <span class="ruby-keyword">do</span>
<span class="ruby-identifier">nodesets</span> = []
<span class="ruby-identifier">nodeset</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">node</span><span class="ruby-operator">|</span>
<span class="ruby-identifier">raw_node</span> = <span class="ruby-identifier">node</span>.<span class="ruby-identifier">raw_node</span>
<span class="ruby-keyword">next</span> <span class="ruby-keyword">unless</span> <span class="ruby-identifier">raw_node</span>.<span class="ruby-identifier">respond_to?</span>(<span class="ruby-value">:parent</span>)
<span class="ruby-keyword">next</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">raw_node</span>.<span class="ruby-identifier">parent</span>.<span class="ruby-identifier">nil?</span>
<span class="ruby-identifier">all_siblings</span> = <span class="ruby-identifier">raw_node</span>.<span class="ruby-identifier">parent</span>.<span class="ruby-identifier">children</span>
<span class="ruby-identifier">current_index</span> = <span class="ruby-identifier">all_siblings</span>.<span class="ruby-identifier">index</span>(<span class="ruby-identifier">raw_node</span>)
<span class="ruby-identifier">following_siblings</span> = <span class="ruby-identifier">all_siblings</span>[(<span class="ruby-identifier">current_index</span> <span class="ruby-operator">+</span> <span class="ruby-value">1</span>)<span class="ruby-operator">..</span><span class="ruby-value">-1</span>]
<span class="ruby-keyword">next</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">following_siblings</span>.<span class="ruby-identifier">empty?</span>
<span class="ruby-identifier">nodesets</span> <span class="ruby-operator"><<</span> <span class="ruby-identifier">following_siblings</span>.<span class="ruby-identifier">collect</span>.<span class="ruby-identifier">with_index</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">sibling</span>, <span class="ruby-identifier">i</span><span class="ruby-operator">|</span>
<span class="ruby-constant">XPathNode</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">sibling</span>, <span class="ruby-value">position:</span> <span class="ruby-identifier">i</span> <span class="ruby-operator">+</span> <span class="ruby-value">1</span>)
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">nodesets</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">when</span> <span class="ruby-value">:preceding_sibling</span>
<span class="ruby-identifier">nodeset</span> = <span class="ruby-identifier">step</span>(<span class="ruby-identifier">path_stack</span>, <span class="ruby-value">order:</span> <span class="ruby-value">:reverse</span>) <span class="ruby-keyword">do</span>
<span class="ruby-identifier">nodesets</span> = []
<span class="ruby-identifier">nodeset</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">node</span><span class="ruby-operator">|</span>
<span class="ruby-identifier">raw_node</span> = <span class="ruby-identifier">node</span>.<span class="ruby-identifier">raw_node</span>
<span class="ruby-keyword">next</span> <span class="ruby-keyword">unless</span> <span class="ruby-identifier">raw_node</span>.<span class="ruby-identifier">respond_to?</span>(<span class="ruby-value">:parent</span>)
<span class="ruby-keyword">next</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">raw_node</span>.<span class="ruby-identifier">parent</span>.<span class="ruby-identifier">nil?</span>
<span class="ruby-identifier">all_siblings</span> = <span class="ruby-identifier">raw_node</span>.<span class="ruby-identifier">parent</span>.<span class="ruby-identifier">children</span>
<span class="ruby-identifier">current_index</span> = <span class="ruby-identifier">all_siblings</span>.<span class="ruby-identifier">index</span>(<span class="ruby-identifier">raw_node</span>)
<span class="ruby-identifier">preceding_siblings</span> = <span class="ruby-identifier">all_siblings</span>[<span class="ruby-value">0</span>, <span class="ruby-identifier">current_index</span>].<span class="ruby-identifier">reverse</span>
<span class="ruby-keyword">next</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">preceding_siblings</span>.<span class="ruby-identifier">empty?</span>
<span class="ruby-identifier">nodesets</span> <span class="ruby-operator"><<</span> <span class="ruby-identifier">preceding_siblings</span>.<span class="ruby-identifier">collect</span>.<span class="ruby-identifier">with_index</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">sibling</span>, <span class="ruby-identifier">i</span><span class="ruby-operator">|</span>
<span class="ruby-constant">XPathNode</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">sibling</span>, <span class="ruby-value">position:</span> <span class="ruby-identifier">i</span> <span class="ruby-operator">+</span> <span class="ruby-value">1</span>)
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">nodesets</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">when</span> <span class="ruby-value">:preceding</span>
<span class="ruby-identifier">nodeset</span> = <span class="ruby-identifier">step</span>(<span class="ruby-identifier">path_stack</span>, <span class="ruby-value">order:</span> <span class="ruby-value">:reverse</span>) <span class="ruby-keyword">do</span>
<span class="ruby-identifier">unnode</span>(<span class="ruby-identifier">nodeset</span>) <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">node</span><span class="ruby-operator">|</span>
<span class="ruby-identifier">preceding</span>(<span class="ruby-identifier">node</span>)
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">when</span> <span class="ruby-value">:following</span>
<span class="ruby-identifier">nodeset</span> = <span class="ruby-identifier">step</span>(<span class="ruby-identifier">path_stack</span>) <span class="ruby-keyword">do</span>
<span class="ruby-identifier">unnode</span>(<span class="ruby-identifier">nodeset</span>) <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">node</span><span class="ruby-operator">|</span>
<span class="ruby-identifier">following</span>(<span class="ruby-identifier">node</span>)
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">when</span> <span class="ruby-value">:variable</span>
<span class="ruby-identifier">var_name</span> = <span class="ruby-identifier">path_stack</span>.<span class="ruby-identifier">shift</span>
<span class="ruby-keyword">return</span> [<span class="ruby-ivar">@variables</span>[<span class="ruby-identifier">var_name</span>]]
<span class="ruby-keyword">when</span> <span class="ruby-value">:eq</span>, <span class="ruby-value">:neq</span>, <span class="ruby-value">:lt</span>, <span class="ruby-value">:lteq</span>, <span class="ruby-value">:gt</span>, <span class="ruby-value">:gteq</span>
<span class="ruby-identifier">left</span> = <span class="ruby-identifier">expr</span>( <span class="ruby-identifier">path_stack</span>.<span class="ruby-identifier">shift</span>, <span class="ruby-identifier">nodeset</span>.<span class="ruby-identifier">dup</span>, <span class="ruby-identifier">context</span> )
<span class="ruby-identifier">right</span> = <span class="ruby-identifier">expr</span>( <span class="ruby-identifier">path_stack</span>.<span class="ruby-identifier">shift</span>, <span class="ruby-identifier">nodeset</span>.<span class="ruby-identifier">dup</span>, <span class="ruby-identifier">context</span> )
<span class="ruby-identifier">res</span> = <span class="ruby-identifier">equality_relational_compare</span>( <span class="ruby-identifier">left</span>, <span class="ruby-identifier">op</span>, <span class="ruby-identifier">right</span> )
<span class="ruby-identifier">trace</span>(<span class="ruby-identifier">op</span>, <span class="ruby-identifier">left</span>, <span class="ruby-identifier">right</span>, <span class="ruby-identifier">res</span>) <span class="ruby-keyword">if</span> <span class="ruby-ivar">@debug</span>
<span class="ruby-keyword">return</span> <span class="ruby-identifier">res</span>
<span class="ruby-keyword">when</span> <span class="ruby-value">:or</span>
<span class="ruby-identifier">left</span> = <span class="ruby-identifier">expr</span>(<span class="ruby-identifier">path_stack</span>.<span class="ruby-identifier">shift</span>, <span class="ruby-identifier">nodeset</span>.<span class="ruby-identifier">dup</span>, <span class="ruby-identifier">context</span>)
<span class="ruby-keyword">return</span> <span class="ruby-keyword">true</span> <span class="ruby-keyword">if</span> <span class="ruby-constant">Functions</span>.<span class="ruby-identifier">boolean</span>(<span class="ruby-identifier">left</span>)
<span class="ruby-identifier">right</span> = <span class="ruby-identifier">expr</span>(<span class="ruby-identifier">path_stack</span>.<span class="ruby-identifier">shift</span>, <span class="ruby-identifier">nodeset</span>.<span class="ruby-identifier">dup</span>, <span class="ruby-identifier">context</span>)
<span class="ruby-keyword">return</span> <span class="ruby-constant">Functions</span>.<span class="ruby-identifier">boolean</span>(<span class="ruby-identifier">right</span>)
<span class="ruby-keyword">when</span> <span class="ruby-value">:and</span>
<span class="ruby-identifier">left</span> = <span class="ruby-identifier">expr</span>(<span class="ruby-identifier">path_stack</span>.<span class="ruby-identifier">shift</span>, <span class="ruby-identifier">nodeset</span>.<span class="ruby-identifier">dup</span>, <span class="ruby-identifier">context</span>)
<span class="ruby-keyword">return</span> <span class="ruby-keyword">false</span> <span class="ruby-keyword">unless</span> <span class="ruby-constant">Functions</span>.<span class="ruby-identifier">boolean</span>(<span class="ruby-identifier">left</span>)
<span class="ruby-identifier">right</span> = <span class="ruby-identifier">expr</span>(<span class="ruby-identifier">path_stack</span>.<span class="ruby-identifier">shift</span>, <span class="ruby-identifier">nodeset</span>.<span class="ruby-identifier">dup</span>, <span class="ruby-identifier">context</span>)
<span class="ruby-keyword">return</span> <span class="ruby-constant">Functions</span>.<span class="ruby-identifier">boolean</span>(<span class="ruby-identifier">right</span>)
<span class="ruby-keyword">when</span> <span class="ruby-value">:div</span>, <span class="ruby-value">:mod</span>, <span class="ruby-value">:mult</span>, <span class="ruby-value">:plus</span>, <span class="ruby-value">:minus</span>
<span class="ruby-identifier">left</span> = <span class="ruby-identifier">expr</span>(<span class="ruby-identifier">path_stack</span>.<span class="ruby-identifier">shift</span>, <span class="ruby-identifier">nodeset</span>, <span class="ruby-identifier">context</span>)
<span class="ruby-identifier">right</span> = <span class="ruby-identifier">expr</span>(<span class="ruby-identifier">path_stack</span>.<span class="ruby-identifier">shift</span>, <span class="ruby-identifier">nodeset</span>, <span class="ruby-identifier">context</span>)
<span class="ruby-identifier">left</span> = <span class="ruby-identifier">unnode</span>(<span class="ruby-identifier">left</span>) <span class="ruby-keyword">if</span> <span class="ruby-identifier">left</span>.<span class="ruby-identifier">is_a?</span>(<span class="ruby-constant">Array</span>)
<span class="ruby-identifier">right</span> = <span class="ruby-identifier">unnode</span>(<span class="ruby-identifier">right</span>) <span class="ruby-keyword">if</span> <span class="ruby-identifier">right</span>.<span class="ruby-identifier">is_a?</span>(<span class="ruby-constant">Array</span>)
<span class="ruby-identifier">left</span> = <span class="ruby-constant">Functions</span><span class="ruby-operator">::</span><span class="ruby-identifier">number</span>(<span class="ruby-identifier">left</span>)
<span class="ruby-identifier">right</span> = <span class="ruby-constant">Functions</span><span class="ruby-operator">::</span><span class="ruby-identifier">number</span>(<span class="ruby-identifier">right</span>)
<span class="ruby-keyword">case</span> <span class="ruby-identifier">op</span>
<span class="ruby-keyword">when</span> <span class="ruby-value">:div</span>
<span class="ruby-keyword">return</span> <span class="ruby-identifier">left</span> <span class="ruby-operator">/</span> <span class="ruby-identifier">right</span>
<span class="ruby-keyword">when</span> <span class="ruby-value">:mod</span>
<span class="ruby-keyword">return</span> <span class="ruby-identifier">left</span> <span class="ruby-operator">%</span> <span class="ruby-identifier">right</span>
<span class="ruby-keyword">when</span> <span class="ruby-value">:mult</span>
<span class="ruby-keyword">return</span> <span class="ruby-identifier">left</span> <span class="ruby-operator">*</span> <span class="ruby-identifier">right</span>
<span class="ruby-keyword">when</span> <span class="ruby-value">:plus</span>
<span class="ruby-keyword">return</span> <span class="ruby-identifier">left</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">right</span>
<span class="ruby-keyword">when</span> <span class="ruby-value">:minus</span>
<span class="ruby-keyword">return</span> <span class="ruby-identifier">left</span> <span class="ruby-operator">-</span> <span class="ruby-identifier">right</span>
<span class="ruby-keyword">else</span>
<span class="ruby-identifier">raise</span> <span class="ruby-node">"[BUG] Unexpected operator: <#{op.inspect}>"</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">when</span> <span class="ruby-value">:union</span>
<span class="ruby-identifier">left</span> = <span class="ruby-identifier">expr</span>( <span class="ruby-identifier">path_stack</span>.<span class="ruby-identifier">shift</span>, <span class="ruby-identifier">nodeset</span>, <span class="ruby-identifier">context</span> )
<span class="ruby-identifier">right</span> = <span class="ruby-identifier">expr</span>( <span class="ruby-identifier">path_stack</span>.<span class="ruby-identifier">shift</span>, <span class="ruby-identifier">nodeset</span>, <span class="ruby-identifier">context</span> )
<span class="ruby-identifier">left</span> = <span class="ruby-identifier">unnode</span>(<span class="ruby-identifier">left</span>) <span class="ruby-keyword">if</span> <span class="ruby-identifier">left</span>.<span class="ruby-identifier">is_a?</span>(<span class="ruby-constant">Array</span>)
<span class="ruby-identifier">right</span> = <span class="ruby-identifier">unnode</span>(<span class="ruby-identifier">right</span>) <span class="ruby-keyword">if</span> <span class="ruby-identifier">right</span>.<span class="ruby-identifier">is_a?</span>(<span class="ruby-constant">Array</span>)
<span class="ruby-keyword">return</span> (<span class="ruby-identifier">left</span> <span class="ruby-operator">|</span> <span class="ruby-identifier">right</span>)
<span class="ruby-keyword">when</span> <span class="ruby-value">:neg</span>
<span class="ruby-identifier">res</span> = <span class="ruby-identifier">expr</span>( <span class="ruby-identifier">path_stack</span>, <span class="ruby-identifier">nodeset</span>, <span class="ruby-identifier">context</span> )
<span class="ruby-identifier">res</span> = <span class="ruby-identifier">unnode</span>(<span class="ruby-identifier">res</span>) <span class="ruby-keyword">if</span> <span class="ruby-identifier">res</span>.<span class="ruby-identifier">is_a?</span>(<span class="ruby-constant">Array</span>)
<span class="ruby-keyword">return</span> <span class="ruby-operator">-</span><span class="ruby-constant">Functions</span>.<span class="ruby-identifier">number</span>(<span class="ruby-identifier">res</span>)
<span class="ruby-keyword">when</span> <span class="ruby-value">:not</span>
<span class="ruby-keyword">when</span> <span class="ruby-value">:function</span>
<span class="ruby-identifier">func_name</span> = <span class="ruby-identifier">path_stack</span>.<span class="ruby-identifier">shift</span>.<span class="ruby-identifier">tr</span>(<span class="ruby-string">'-'</span>,<span class="ruby-string">'_'</span>)
<span class="ruby-identifier">arguments</span> = <span class="ruby-identifier">path_stack</span>.<span class="ruby-identifier">shift</span>
<span class="ruby-keyword">if</span> <span class="ruby-identifier">nodeset</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">!=</span> <span class="ruby-value">1</span>
<span class="ruby-identifier">message</span> = <span class="ruby-string">"[BUG] Node set size must be 1 for function call: "</span>
<span class="ruby-identifier">message</span> <span class="ruby-operator">+=</span> <span class="ruby-node">"<#{func_name}>: <#{nodeset.inspect}>: "</span>
<span class="ruby-identifier">message</span> <span class="ruby-operator">+=</span> <span class="ruby-node">"<#{arguments.inspect}>"</span>
<span class="ruby-identifier">raise</span> <span class="ruby-identifier">message</span>
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">node</span> = <span class="ruby-identifier">nodeset</span>.<span class="ruby-identifier">first</span>
<span class="ruby-keyword">if</span> <span class="ruby-identifier">context</span>
<span class="ruby-identifier">target_context</span> = <span class="ruby-identifier">context</span>
<span class="ruby-keyword">else</span>
<span class="ruby-identifier">target_context</span> = {<span class="ruby-value">:size</span> <span class="ruby-operator">=></span> <span class="ruby-identifier">nodeset</span>.<span class="ruby-identifier">size</span>}
<span class="ruby-keyword">if</span> <span class="ruby-identifier">node</span>.<span class="ruby-identifier">is_a?</span>(<span class="ruby-constant">XPathNode</span>)
<span class="ruby-identifier">target_context</span>[<span class="ruby-value">:node</span>] = <span class="ruby-identifier">node</span>.<span class="ruby-identifier">raw_node</span>
<span class="ruby-identifier">target_context</span>[<span class="ruby-value">:index</span>] = <span class="ruby-identifier">node</span>.<span class="ruby-identifier">position</span>
<span class="ruby-keyword">else</span>
<span class="ruby-identifier">target_context</span>[<span class="ruby-value">:node</span>] = <span class="ruby-identifier">node</span>
<span class="ruby-identifier">target_context</span>[<span class="ruby-value">:index</span>] = <span class="ruby-value">1</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">args</span> = <span class="ruby-identifier">arguments</span>.<span class="ruby-identifier">dclone</span>.<span class="ruby-identifier">collect</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">arg</span><span class="ruby-operator">|</span>
<span class="ruby-identifier">result</span> = <span class="ruby-identifier">expr</span>(<span class="ruby-identifier">arg</span>, <span class="ruby-identifier">nodeset</span>, <span class="ruby-identifier">target_context</span>)
<span class="ruby-identifier">result</span> = <span class="ruby-identifier">unnode</span>(<span class="ruby-identifier">result</span>) <span class="ruby-keyword">if</span> <span class="ruby-identifier">result</span>.<span class="ruby-identifier">is_a?</span>(<span class="ruby-constant">Array</span>)
<span class="ruby-identifier">result</span>
<span class="ruby-keyword">end</span>
<span class="ruby-constant">Functions</span>.<span class="ruby-identifier">context</span> = <span class="ruby-identifier">target_context</span>
<span class="ruby-keyword">return</span> <span class="ruby-constant">Functions</span>.<span class="ruby-identifier">send</span>(<span class="ruby-identifier">func_name</span>, <span class="ruby-operator">*</span><span class="ruby-identifier">args</span>)
<span class="ruby-keyword">else</span>
<span class="ruby-identifier">raise</span> <span class="ruby-node">"[BUG] Unexpected path: <#{op.inspect}>: <#{path_stack.inspect}>"</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span> <span class="ruby-comment"># while</span>
<span class="ruby-keyword">return</span> <span class="ruby-identifier">nodeset</span>
<span class="ruby-keyword">ensure</span>
<span class="ruby-identifier">leave</span>(<span class="ruby-value">:expr</span>, <span class="ruby-identifier">path_stack</span>, <span class="ruby-identifier">nodeset</span>) <span class="ruby-keyword">if</span> <span class="ruby-ivar">@debug</span>
<span class="ruby-keyword">end</span></pre>
</div>
</div>
</div>
<div id="method-i-filter_nodeset" class="method-detail ">
<div class="method-heading">
<span class="method-name">filter_nodeset</span><span
class="method-args">(nodeset) { |node| ... }</span>
<span class="method-click-advice">click to toggle source</span>
</div>
<div class="method-description">
<div class="method-source-code" id="filter_nodeset-source">
<pre><span class="ruby-comment"># File lib/rexml/xpath_parser.rb, line 576</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">filter_nodeset</span>(<span class="ruby-identifier">nodeset</span>)
<span class="ruby-identifier">new_nodeset</span> = []
<span class="ruby-identifier">nodeset</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">node</span><span class="ruby-operator">|</span>
<span class="ruby-keyword">next</span> <span class="ruby-keyword">unless</span> <span class="ruby-keyword">yield</span>(<span class="ruby-identifier">node</span>)
<span class="ruby-identifier">new_nodeset</span> <span class="ruby-operator"><<</span> <span class="ruby-constant">XPathNode</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">node</span>, <span class="ruby-value">position:</span> <span class="ruby-identifier">new_nodeset</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">+</span> <span class="ruby-value">1</span>)
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">new_nodeset</span>
<span class="ruby-keyword">end</span></pre>
</div>
</div>
</div>
<div id="method-i-following" class="method-detail ">
<div class="method-heading">
<span class="method-name">following</span><span
class="method-args">(node)</span>
<span class="method-click-advice">click to toggle source</span>
</div>
<div class="method-description">
<div class="method-source-code" id="following-source">
<pre><span class="ruby-comment"># File lib/rexml/xpath_parser.rb, line 739</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">following</span>(<span class="ruby-identifier">node</span>)
<span class="ruby-identifier">followings</span> = []
<span class="ruby-identifier">following_node</span> = <span class="ruby-identifier">next_sibling_node</span>(<span class="ruby-identifier">node</span>)
<span class="ruby-keyword">while</span> <span class="ruby-identifier">following_node</span>
<span class="ruby-identifier">followings</span> <span class="ruby-operator"><<</span> <span class="ruby-constant">XPathNode</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">following_node</span>,
<span class="ruby-value">position:</span> <span class="ruby-identifier">followings</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">+</span> <span class="ruby-value">1</span>)
<span class="ruby-identifier">following_node</span> = <span class="ruby-identifier">following_node_of</span>(<span class="ruby-identifier">following_node</span>)
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">followings</span>
<span class="ruby-keyword">end</span></pre>
</div>
</div>
</div>
<div id="method-i-following_node_of" class="method-detail ">
<div class="method-heading">
<span class="method-name">following_node_of</span><span
class="method-args">( node )</span>
<span class="method-click-advice">click to toggle source</span>
</div>
<div class="method-description">
<div class="method-source-code" id="following_node_of-source">
<pre><span class="ruby-comment"># File lib/rexml/xpath_parser.rb, line 750</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">following_node_of</span>( <span class="ruby-identifier">node</span> )
<span class="ruby-keyword">if</span> <span class="ruby-identifier">node</span>.<span class="ruby-identifier">kind_of?</span> <span class="ruby-constant">Element</span> <span class="ruby-keyword">and</span> <span class="ruby-identifier">node</span>.<span class="ruby-identifier">children</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">></span> <span class="ruby-value">0</span>
<span class="ruby-keyword">return</span> <span class="ruby-identifier">node</span>.<span class="ruby-identifier">children</span>[<span class="ruby-value">0</span>]
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">return</span> <span class="ruby-identifier">next_sibling_node</span>(<span class="ruby-identifier">node</span>)
<span class="ruby-keyword">end</span></pre>
</div>
</div>
</div>
<div id="method-i-get_namespace" class="method-detail ">
<div class="method-heading">
<span class="method-name">get_namespace</span><span
class="method-args">( node, prefix )</span>
<span class="method-click-advice">click to toggle source</span>
</div>
<div class="method-description">
<p>Returns a <a href="../String.html"><code>String</code></a> namespace for a node, given a prefix The rules are:</p>
<pre>1. Use the supplied namespace mapping first.
2. If no mapping was supplied, use the context node to look up the namespace</pre>
<div class="method-source-code" id="get_namespace-source">
<pre><span class="ruby-comment"># File lib/rexml/xpath_parser.rb, line 157</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">get_namespace</span>( <span class="ruby-identifier">node</span>, <span class="ruby-identifier">prefix</span> )
<span class="ruby-keyword">if</span> <span class="ruby-ivar">@namespaces</span>
<span class="ruby-keyword">return</span> <span class="ruby-ivar">@namespaces</span>[<span class="ruby-identifier">prefix</span>] <span class="ruby-operator">||</span> <span class="ruby-string">''</span>
<span class="ruby-keyword">else</span>
<span class="ruby-keyword">return</span> <span class="ruby-identifier">node</span>.<span class="ruby-identifier">namespace</span>( <span class="ruby-identifier">prefix</span> ) <span class="ruby-keyword">if</span> <span class="ruby-identifier">node</span>.<span class="ruby-identifier">node_type</span> <span class="ruby-operator">==</span> <span class="ruby-value">:element</span>
<span class="ruby-keyword">return</span> <span class="ruby-string">''</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span></pre>
</div>
</div>
</div>
<div id="method-i-leave" class="method-detail ">
<div class="method-heading">
<span class="method-name">leave</span><span
class="method-args">(tag, *args)</span>
<span class="method-click-advice">click to toggle source</span>
</div>
<div class="method-description">
<div class="method-source-code" id="leave-source">
<pre><span class="ruby-comment"># File lib/rexml/xpath_parser.rb, line 636</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">leave</span>(<span class="ruby-identifier">tag</span>, <span class="ruby-operator">*</span><span class="ruby-identifier">args</span>)
<span class="ruby-ivar">@nest</span> <span class="ruby-operator">-=</span> <span class="ruby-value">1</span>
<span class="ruby-identifier">trace</span>(<span class="ruby-value">:leave</span>, <span class="ruby-identifier">tag</span>, <span class="ruby-operator">*</span><span class="ruby-identifier">args</span>)
<span class="ruby-keyword">end</span></pre>
</div>
</div>
</div>
<div id="method-i-next_sibling_node" class="method-detail ">
<div class="method-heading">
<span class="method-name">next_sibling_node</span><span
class="method-args">(node)</span>
<span class="method-click-advice">click to toggle source</span>
</div>
<div class="method-description">
<div class="method-source-code" id="next_sibling_node-source">
<pre><span class="ruby-comment"># File lib/rexml/xpath_parser.rb, line 757</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">next_sibling_node</span>(<span class="ruby-identifier">node</span>)
<span class="ruby-identifier">psn</span> = <span class="ruby-identifier">node</span>.<span class="ruby-identifier">next_sibling_node</span>
<span class="ruby-keyword">while</span> <span class="ruby-identifier">psn</span>.<span class="ruby-identifier">nil?</span>
<span class="ruby-keyword">if</span> <span class="ruby-identifier">node</span>.<span class="ruby-identifier">parent</span>.<span class="ruby-identifier">nil?</span> <span class="ruby-keyword">or</span> <span class="ruby-identifier">node</span>.<span class="ruby-identifier">parent</span>.<span class="ruby-identifier">class</span> <span class="ruby-operator">==</span> <span class="ruby-constant">Document</span>
<span class="ruby-keyword">return</span> <span class="ruby-keyword">nil</span>
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">node</span> = <span class="ruby-identifier">node</span>.<span class="ruby-identifier">parent</span>
<span class="ruby-identifier">psn</span> = <span class="ruby-identifier">node</span>.<span class="ruby-identifier">next_sibling_node</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">return</span> <span class="ruby-identifier">psn</span>
<span class="ruby-keyword">end</span></pre>
</div>
</div>
</div>
<div id="method-i-node_test" class="method-detail ">
<div class="method-heading">
<span class="method-name">node_test</span><span
class="method-args">(path_stack, nodesets, any_type: :element)</span>
<span class="method-click-advice">click to toggle source</span>
</div>
<div class="method-description">
<div class="method-source-code" id="node_test-source">
<pre><span class="ruby-comment"># File lib/rexml/xpath_parser.rb, line 471</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">node_test</span>(<span class="ruby-identifier">path_stack</span>, <span class="ruby-identifier">nodesets</span>, <span class="ruby-value">any_type:</span> <span class="ruby-value">:element</span>)
<span class="ruby-identifier">enter</span>(<span class="ruby-value">:node_test</span>, <span class="ruby-identifier">path_stack</span>, <span class="ruby-identifier">nodesets</span>) <span class="ruby-keyword">if</span> <span class="ruby-ivar">@debug</span>
<span class="ruby-identifier">operator</span> = <span class="ruby-identifier">path_stack</span>.<span class="ruby-identifier">shift</span>
<span class="ruby-keyword">case</span> <span class="ruby-identifier">operator</span>
<span class="ruby-keyword">when</span> <span class="ruby-value">:qname</span>
<span class="ruby-identifier">prefix</span> = <span class="ruby-identifier">path_stack</span>.<span class="ruby-identifier">shift</span>
<span class="ruby-identifier">name</span> = <span class="ruby-identifier">path_stack</span>.<span class="ruby-identifier">shift</span>
<span class="ruby-identifier">new_nodesets</span> = <span class="ruby-identifier">nodesets</span>.<span class="ruby-identifier">collect</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">nodeset</span><span class="ruby-operator">|</span>
<span class="ruby-identifier">filter_nodeset</span>(<span class="ruby-identifier">nodeset</span>) <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">node</span><span class="ruby-operator">|</span>
<span class="ruby-identifier">raw_node</span> = <span class="ruby-identifier">node</span>.<span class="ruby-identifier">raw_node</span>
<span class="ruby-keyword">case</span> <span class="ruby-identifier">raw_node</span>.<span class="ruby-identifier">node_type</span>
<span class="ruby-keyword">when</span> <span class="ruby-value">:element</span>
<span class="ruby-keyword">if</span> <span class="ruby-identifier">prefix</span>.<span class="ruby-identifier">nil?</span>
<span class="ruby-identifier">raw_node</span>.<span class="ruby-identifier">name</span> <span class="ruby-operator">==</span> <span class="ruby-identifier">name</span>
<span class="ruby-keyword">elsif</span> <span class="ruby-identifier">prefix</span>.<span class="ruby-identifier">empty?</span>
<span class="ruby-keyword">if</span> <span class="ruby-identifier">strict?</span>
<span class="ruby-identifier">raw_node</span>.<span class="ruby-identifier">name</span> <span class="ruby-operator">==</span> <span class="ruby-identifier">name</span> <span class="ruby-keyword">and</span> <span class="ruby-identifier">raw_node</span>.<span class="ruby-identifier">namespace</span> <span class="ruby-operator">==</span> <span class="ruby-string">""</span>
<span class="ruby-keyword">else</span>
<span class="ruby-comment"># FIXME: This DOUBLES the time XPath searches take</span>
<span class="ruby-identifier">ns</span> = <span class="ruby-identifier">get_namespace</span>(<span class="ruby-identifier">raw_node</span>, <span class="ruby-identifier">prefix</span>)
<span class="ruby-identifier">raw_node</span>.<span class="ruby-identifier">name</span> <span class="ruby-operator">==</span> <span class="ruby-identifier">name</span> <span class="ruby-keyword">and</span> <span class="ruby-identifier">raw_node</span>.<span class="ruby-identifier">namespace</span> <span class="ruby-operator">==</span> <span class="ruby-identifier">ns</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">else</span>
<span class="ruby-comment"># FIXME: This DOUBLES the time XPath searches take</span>
<span class="ruby-identifier">ns</span> = <span class="ruby-identifier">get_namespace</span>(<span class="ruby-identifier">raw_node</span>, <span class="ruby-identifier">prefix</span>)
<span class="ruby-identifier">raw_node</span>.<span class="ruby-identifier">name</span> <span class="ruby-operator">==</span> <span class="ruby-identifier">name</span> <span class="ruby-keyword">and</span> <span class="ruby-identifier">raw_node</span>.<span class="ruby-identifier">namespace</span> <span class="ruby-operator">==</span> <span class="ruby-identifier">ns</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">when</span> <span class="ruby-value">:attribute</span>
<span class="ruby-keyword">if</span> <span class="ruby-identifier">prefix</span>.<span class="ruby-identifier">nil?</span>
<span class="ruby-identifier">raw_node</span>.<span class="ruby-identifier">name</span> <span class="ruby-operator">==</span> <span class="ruby-identifier">name</span>
<span class="ruby-keyword">elsif</span> <span class="ruby-identifier">prefix</span>.<span class="ruby-identifier">empty?</span>
<span class="ruby-identifier">raw_node</span>.<span class="ruby-identifier">name</span> <span class="ruby-operator">==</span> <span class="ruby-identifier">name</span> <span class="ruby-keyword">and</span> <span class="ruby-identifier">raw_node</span>.<span class="ruby-identifier">namespace</span> <span class="ruby-operator">==</span> <span class="ruby-string">""</span>
<span class="ruby-keyword">else</span>
<span class="ruby-comment"># FIXME: This DOUBLES the time XPath searches take</span>
<span class="ruby-identifier">ns</span> = <span class="ruby-identifier">get_namespace</span>(<span class="ruby-identifier">raw_node</span>.<span class="ruby-identifier">element</span>, <span class="ruby-identifier">prefix</span>)
<span class="ruby-identifier">raw_node</span>.<span class="ruby-identifier">name</span> <span class="ruby-operator">==</span> <span class="ruby-identifier">name</span> <span class="ruby-keyword">and</span> <span class="ruby-identifier">raw_node</span>.<span class="ruby-identifier">namespace</span> <span class="ruby-operator">==</span> <span class="ruby-identifier">ns</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">else</span>
<span class="ruby-keyword">false</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">when</span> <span class="ruby-value">:namespace</span>
<span class="ruby-identifier">prefix</span> = <span class="ruby-identifier">path_stack</span>.<span class="ruby-identifier">shift</span>
<span class="ruby-identifier">new_nodesets</span> = <span class="ruby-identifier">nodesets</span>.<span class="ruby-identifier">collect</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">nodeset</span><span class="ruby-operator">|</span>
<span class="ruby-identifier">filter_nodeset</span>(<span class="ruby-identifier">nodeset</span>) <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">node</span><span class="ruby-operator">|</span>
<span class="ruby-identifier">raw_node</span> = <span class="ruby-identifier">node</span>.<span class="ruby-identifier">raw_node</span>
<span class="ruby-keyword">case</span> <span class="ruby-identifier">raw_node</span>.<span class="ruby-identifier">node_type</span>
<span class="ruby-keyword">when</span> <span class="ruby-value">:element</span>
<span class="ruby-identifier">namespaces</span> = <span class="ruby-ivar">@namespaces</span> <span class="ruby-operator">||</span> <span class="ruby-identifier">raw_node</span>.<span class="ruby-identifier">namespaces</span>
<span class="ruby-identifier">raw_node</span>.<span class="ruby-identifier">namespace</span> <span class="ruby-operator">==</span> <span class="ruby-identifier">namespaces</span>[<span class="ruby-identifier">prefix</span>]
<span class="ruby-keyword">when</span> <span class="ruby-value">:attribute</span>
<span class="ruby-identifier">namespaces</span> = <span class="ruby-ivar">@namespaces</span> <span class="ruby-operator">||</span> <span class="ruby-identifier">raw_node</span>.<span class="ruby-identifier">element</span>.<span class="ruby-identifier">namespaces</span>
<span class="ruby-identifier">raw_node</span>.<span class="ruby-identifier">namespace</span> <span class="ruby-operator">==</span> <span class="ruby-identifier">namespaces</span>[<span class="ruby-identifier">prefix</span>]
<span class="ruby-keyword">else</span>
<span class="ruby-keyword">false</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">when</span> <span class="ruby-value">:any</span>
<span class="ruby-identifier">new_nodesets</span> = <span class="ruby-identifier">nodesets</span>.<span class="ruby-identifier">collect</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">nodeset</span><span class="ruby-operator">|</span>
<span class="ruby-identifier">filter_nodeset</span>(<span class="ruby-identifier">nodeset</span>) <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">node</span><span class="ruby-operator">|</span>
<span class="ruby-identifier">raw_node</span> = <span class="ruby-identifier">node</span>.<span class="ruby-identifier">raw_node</span>
<span class="ruby-identifier">raw_node</span>.<span class="ruby-identifier">node_type</span> <span class="ruby-operator">==</span> <span class="ruby-identifier">any_type</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">when</span> <span class="ruby-value">:comment</span>
<span class="ruby-identifier">new_nodesets</span> = <span class="ruby-identifier">nodesets</span>.<span class="ruby-identifier">collect</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">nodeset</span><span class="ruby-operator">|</span>
<span class="ruby-identifier">filter_nodeset</span>(<span class="ruby-identifier">nodeset</span>) <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">node</span><span class="ruby-operator">|</span>
<span class="ruby-identifier">raw_node</span> = <span class="ruby-identifier">node</span>.<span class="ruby-identifier">raw_node</span>
<span class="ruby-identifier">raw_node</span>.<span class="ruby-identifier">node_type</span> <span class="ruby-operator">==</span> <span class="ruby-value">:comment</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">when</span> <span class="ruby-value">:text</span>
<span class="ruby-identifier">new_nodesets</span> = <span class="ruby-identifier">nodesets</span>.<span class="ruby-identifier">collect</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">nodeset</span><span class="ruby-operator">|</span>
<span class="ruby-identifier">filter_nodeset</span>(<span class="ruby-identifier">nodeset</span>) <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">node</span><span class="ruby-operator">|</span>
<span class="ruby-identifier">raw_node</span> = <span class="ruby-identifier">node</span>.<span class="ruby-identifier">raw_node</span>
<span class="ruby-identifier">raw_node</span>.<span class="ruby-identifier">node_type</span> <span class="ruby-operator">==</span> <span class="ruby-value">:text</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">when</span> <span class="ruby-value">:processing_instruction</span>
<span class="ruby-identifier">target</span> = <span class="ruby-identifier">path_stack</span>.<span class="ruby-identifier">shift</span>
<span class="ruby-identifier">new_nodesets</span> = <span class="ruby-identifier">nodesets</span>.<span class="ruby-identifier">collect</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">nodeset</span><span class="ruby-operator">|</span>
<span class="ruby-identifier">filter_nodeset</span>(<span class="ruby-identifier">nodeset</span>) <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">node</span><span class="ruby-operator">|</span>
<span class="ruby-identifier">raw_node</span> = <span class="ruby-identifier">node</span>.<span class="ruby-identifier">raw_node</span>
(<span class="ruby-identifier">raw_node</span>.<span class="ruby-identifier">node_type</span> <span class="ruby-operator">==</span> <span class="ruby-value">:processing_instruction</span>) <span class="ruby-keyword">and</span>
(<span class="ruby-identifier">target</span>.<span class="ruby-identifier">empty?</span> <span class="ruby-keyword">or</span> (<span class="ruby-identifier">raw_node</span>.<span class="ruby-identifier">target</span> <span class="ruby-operator">==</span> <span class="ruby-identifier">target</span>))
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">when</span> <span class="ruby-value">:node</span>
<span class="ruby-identifier">new_nodesets</span> = <span class="ruby-identifier">nodesets</span>.<span class="ruby-identifier">collect</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">nodeset</span><span class="ruby-operator">|</span>
<span class="ruby-identifier">filter_nodeset</span>(<span class="ruby-identifier">nodeset</span>) <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">node</span><span class="ruby-operator">|</span>
<span class="ruby-keyword">true</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">else</span>
<span class="ruby-identifier">message</span> = <span class="ruby-string">"[BUG] Unexpected node test: "</span> <span class="ruby-operator">+</span>
<span class="ruby-node">"<#{operator.inspect}>: <#{path_stack.inspect}>"</span>
<span class="ruby-identifier">raise</span> <span class="ruby-identifier">message</span>
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">new_nodesets</span>
<span class="ruby-keyword">ensure</span>
<span class="ruby-identifier">leave</span>(<span class="ruby-value">:node_test</span>, <span class="ruby-identifier">path_stack</span>, <span class="ruby-identifier">new_nodesets</span>) <span class="ruby-keyword">if</span> <span class="ruby-ivar">@debug</span>
<span class="ruby-keyword">end</span></pre>
</div>
</div>
</div>
<div id="method-i-norm" class="method-detail ">
<div class="method-heading">
<span class="method-name">norm</span><span
class="method-args">(b)</span>
<span class="method-click-advice">click to toggle source</span>
</div>
<div class="method-description">
<div class="method-source-code" id="norm-source">
<pre><span class="ruby-comment"># File lib/rexml/xpath_parser.rb, line 796</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">norm</span> <span class="ruby-identifier">b</span>
<span class="ruby-keyword">case</span> <span class="ruby-identifier">b</span>
<span class="ruby-keyword">when</span> <span class="ruby-keyword">true</span>, <span class="ruby-keyword">false</span>
<span class="ruby-keyword">return</span> <span class="ruby-identifier">b</span>
<span class="ruby-keyword">when</span> <span class="ruby-string">'true'</span>, <span class="ruby-string">'false'</span>
<span class="ruby-keyword">return</span> <span class="ruby-constant">Functions</span><span class="ruby-operator">::</span><span class="ruby-identifier">boolean</span>( <span class="ruby-identifier">b</span> )
<span class="ruby-keyword">when</span> <span class="ruby-regexp">/^\d+(\.\d+)?$/</span>, <span class="ruby-constant">Numeric</span>
<span class="ruby-keyword">return</span> <span class="ruby-constant">Functions</span><span class="ruby-operator">::</span><span class="ruby-identifier">number</span>( <span class="ruby-identifier">b</span> )
<span class="ruby-keyword">else</span>
<span class="ruby-keyword">return</span> <span class="ruby-constant">Functions</span><span class="ruby-operator">::</span><span class="ruby-identifier">string</span>( <span class="ruby-identifier">b</span> )
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span></pre>
</div>
</div>
</div>
<div id="method-i-normalize_compare_values" class="method-detail ">
<div class="method-heading">
<span class="method-name">normalize_compare_values</span><span
class="method-args">(a, operator, b)</span>
<span class="method-click-advice">click to toggle source</span>
</div>
<div class="method-description">
<div class="method-source-code" id="normalize_compare_values-source">
<pre><span class="ruby-comment"># File lib/rexml/xpath_parser.rb, line 884</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">normalize_compare_values</span>(<span class="ruby-identifier">a</span>, <span class="ruby-identifier">operator</span>, <span class="ruby-identifier">b</span>)
<span class="ruby-identifier">a_type</span> = <span class="ruby-identifier">value_type</span>(<span class="ruby-identifier">a</span>)
<span class="ruby-identifier">b_type</span> = <span class="ruby-identifier">value_type</span>(<span class="ruby-identifier">b</span>)
<span class="ruby-keyword">case</span> <span class="ruby-identifier">operator</span>
<span class="ruby-keyword">when</span> <span class="ruby-value">:eq</span>, <span class="ruby-value">:neq</span>
<span class="ruby-keyword">if</span> <span class="ruby-identifier">a_type</span> <span class="ruby-operator">==</span> <span class="ruby-value">:boolean</span> <span class="ruby-keyword">or</span> <span class="ruby-identifier">b_type</span> <span class="ruby-operator">==</span> <span class="ruby-value">:boolean</span>
<span class="ruby-identifier">a</span> = <span class="ruby-constant">Functions</span>.<span class="ruby-identifier">boolean</span>(<span class="ruby-identifier">a</span>) <span class="ruby-keyword">unless</span> <span class="ruby-identifier">a_type</span> <span class="ruby-operator">==</span> <span class="ruby-value">:boolean</span>
<span class="ruby-identifier">b</span> = <span class="ruby-constant">Functions</span>.<span class="ruby-identifier">boolean</span>(<span class="ruby-identifier">b</span>) <span class="ruby-keyword">unless</span> <span class="ruby-identifier">b_type</span> <span class="ruby-operator">==</span> <span class="ruby-value">:boolean</span>
<span class="ruby-keyword">elsif</span> <span class="ruby-identifier">a_type</span> <span class="ruby-operator">==</span> <span class="ruby-value">:number</span> <span class="ruby-keyword">or</span> <span class="ruby-identifier">b_type</span> <span class="ruby-operator">==</span> <span class="ruby-value">:number</span>
<span class="ruby-identifier">a</span> = <span class="ruby-constant">Functions</span>.<span class="ruby-identifier">number</span>(<span class="ruby-identifier">a</span>) <span class="ruby-keyword">unless</span> <span class="ruby-identifier">a_type</span> <span class="ruby-operator">==</span> <span class="ruby-value">:number</span>
<span class="ruby-identifier">b</span> = <span class="ruby-constant">Functions</span>.<span class="ruby-identifier">number</span>(<span class="ruby-identifier">b</span>) <span class="ruby-keyword">unless</span> <span class="ruby-identifier">b_type</span> <span class="ruby-operator">==</span> <span class="ruby-value">:number</span>
<span class="ruby-keyword">else</span>
<span class="ruby-identifier">a</span> = <span class="ruby-constant">Functions</span>.<span class="ruby-identifier">string</span>(<span class="ruby-identifier">a</span>) <span class="ruby-keyword">unless</span> <span class="ruby-identifier">a_type</span> <span class="ruby-operator">==</span> <span class="ruby-value">:string</span>
<span class="ruby-identifier">b</span> = <span class="ruby-constant">Functions</span>.<span class="ruby-identifier">string</span>(<span class="ruby-identifier">b</span>) <span class="ruby-keyword">unless</span> <span class="ruby-identifier">b_type</span> <span class="ruby-operator">==</span> <span class="ruby-value">:string</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">when</span> <span class="ruby-value">:lt</span>, <span class="ruby-value">:lteq</span>, <span class="ruby-value">:gt</span>, <span class="ruby-value">:gteq</span>
<span class="ruby-identifier">a</span> = <span class="ruby-constant">Functions</span>.<span class="ruby-identifier">number</span>(<span class="ruby-identifier">a</span>) <span class="ruby-keyword">unless</span> <span class="ruby-identifier">a_type</span> <span class="ruby-operator">==</span> <span class="ruby-value">:number</span>
<span class="ruby-identifier">b</span> = <span class="ruby-constant">Functions</span>.<span class="ruby-identifier">number</span>(<span class="ruby-identifier">b</span>) <span class="ruby-keyword">unless</span> <span class="ruby-identifier">b_type</span> <span class="ruby-operator">==</span> <span class="ruby-value">:number</span>
<span class="ruby-keyword">else</span>
<span class="ruby-identifier">message</span> = <span class="ruby-string">"[BUG] Unexpected compare operator: "</span> <span class="ruby-operator">+</span>
<span class="ruby-node">"<#{operator.inspect}>: <#{a.inspect}>: <#{b.inspect}>"</span>
<span class="ruby-identifier">raise</span> <span class="ruby-identifier">message</span>
<span class="ruby-keyword">end</span>
[<span class="ruby-identifier">a</span>, <span class="ruby-identifier">b</span>]
<span class="ruby-keyword">end</span></pre>
</div>
</div>
</div>
<div id="method-i-preceding" class="method-detail ">
<div class="method-heading">
<span class="method-name">preceding</span><span
class="method-args">(node)</span>
<span class="method-click-advice">click to toggle source</span>
</div>
<div class="method-description">
<p>Builds a nodeset of all of the preceding nodes of the supplied node, in reverse document order</p>
<dl class="rdoc-list note-list"><dt>preceding
<dd>
<p>includes every element in the document that precedes this node,</p>
</dd></dl>
<p>except for ancestors</p>
<div class="method-source-code" id="preceding-source">
<pre><span class="ruby-comment"># File lib/rexml/xpath_parser.rb, line 702</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">preceding</span>(<span class="ruby-identifier">node</span>)
<span class="ruby-identifier">ancestors</span> = []
<span class="ruby-identifier">parent</span> = <span class="ruby-identifier">node</span>.<span class="ruby-identifier">parent</span>
<span class="ruby-keyword">while</span> <span class="ruby-identifier">parent</span>
<span class="ruby-identifier">ancestors</span> <span class="ruby-operator"><<</span> <span class="ruby-identifier">parent</span>
<span class="ruby-identifier">parent</span> = <span class="ruby-identifier">parent</span>.<span class="ruby-identifier">parent</span>
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">precedings</span> = []
<span class="ruby-identifier">preceding_node</span> = <span class="ruby-identifier">preceding_node_of</span>(<span class="ruby-identifier">node</span>)
<span class="ruby-keyword">while</span> <span class="ruby-identifier">preceding_node</span>
<span class="ruby-keyword">if</span> <span class="ruby-identifier">ancestors</span>.<span class="ruby-identifier">include?</span>(<span class="ruby-identifier">preceding_node</span>)
<span class="ruby-identifier">ancestors</span>.<span class="ruby-identifier">delete</span>(<span class="ruby-identifier">preceding_node</span>)
<span class="ruby-keyword">else</span>
<span class="ruby-identifier">precedings</span> <span class="ruby-operator"><<</span> <span class="ruby-constant">XPathNode</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">preceding_node</span>,
<span class="ruby-value">position:</span> <span class="ruby-identifier">precedings</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">+</span> <span class="ruby-value">1</span>)
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">preceding_node</span> = <span class="ruby-identifier">preceding_node_of</span>(<span class="ruby-identifier">preceding_node</span>)
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">precedings</span>
<span class="ruby-keyword">end</span></pre>
</div>
</div>
</div>
<div id="method-i-preceding_node_of" class="method-detail ">
<div class="method-heading">
<span class="method-name">preceding_node_of</span><span
class="method-args">( node )</span>
<span class="method-click-advice">click to toggle source</span>
</div>
<div class="method-description">
<div class="method-source-code" id="preceding_node_of-source">
<pre><span class="ruby-comment"># File lib/rexml/xpath_parser.rb, line 724</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">preceding_node_of</span>( <span class="ruby-identifier">node</span> )
<span class="ruby-identifier">psn</span> = <span class="ruby-identifier">node</span>.<span class="ruby-identifier">previous_sibling_node</span>
<span class="ruby-keyword">if</span> <span class="ruby-identifier">psn</span>.<span class="ruby-identifier">nil?</span>
<span class="ruby-keyword">if</span> <span class="ruby-identifier">node</span>.<span class="ruby-identifier">parent</span>.<span class="ruby-identifier">nil?</span> <span class="ruby-keyword">or</span> <span class="ruby-identifier">node</span>.<span class="ruby-identifier">parent</span>.<span class="ruby-identifier">class</span> <span class="ruby-operator">==</span> <span class="ruby-constant">Document</span>
<span class="ruby-keyword">return</span> <span class="ruby-keyword">nil</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">return</span> <span class="ruby-identifier">node</span>.<span class="ruby-identifier">parent</span>
<span class="ruby-comment">#psn = preceding_node_of( node.parent )</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">while</span> <span class="ruby-identifier">psn</span> <span class="ruby-keyword">and</span> <span class="ruby-identifier">psn</span>.<span class="ruby-identifier">kind_of?</span> <span class="ruby-constant">Element</span> <span class="ruby-keyword">and</span> <span class="ruby-identifier">psn</span>.<span class="ruby-identifier">children</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">></span> <span class="ruby-value">0</span>
<span class="ruby-identifier">psn</span> = <span class="ruby-identifier">psn</span>.<span class="ruby-identifier">children</span>[<span class="ruby-value">-1</span>]
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">psn</span>
<span class="ruby-keyword">end</span></pre>
</div>
</div>
</div>
<div id="method-i-sort" class="method-detail ">
<div class="method-heading">
<span class="method-name">sort</span><span
class="method-args">(array_of_nodes, order)</span>
<span class="method-click-advice">click to toggle source</span>
</div>
<div class="method-description">
<p>Reorders an array of nodes so that they are in document order It tries to do this efficiently.</p>
<p>FIXME: I need to get rid of this, but the issue is that most of the <a href="XPath.html"><code>XPath</code></a> interpreter functions as a filter, which means that we lose context going in and out of function calls. If I knew what the index of the nodes was, I wouldn't have to do this. Maybe add a document IDX for each node? Problems with mutable documents. Or, rewrite everything.</p>
<div class="method-source-code" id="sort-source">
<pre><span class="ruby-comment"># File lib/rexml/xpath_parser.rb, line 649</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">sort</span>(<span class="ruby-identifier">array_of_nodes</span>, <span class="ruby-identifier">order</span>)
<span class="ruby-identifier">new_arry</span> = []
<span class="ruby-identifier">array_of_nodes</span>.<span class="ruby-identifier">each</span> { <span class="ruby-operator">|</span><span class="ruby-identifier">node</span><span class="ruby-operator">|</span>
<span class="ruby-identifier">node_idx</span> = []
<span class="ruby-identifier">np</span> = <span class="ruby-identifier">node</span>.<span class="ruby-identifier">node_type</span> <span class="ruby-operator">==</span> <span class="ruby-value">:attribute</span> <span class="ruby-operator">?</span> <span class="ruby-identifier">node</span>.<span class="ruby-identifier">element</span> <span class="ruby-operator">:</span> <span class="ruby-identifier">node</span>
<span class="ruby-keyword">while</span> <span class="ruby-identifier">np</span>.<span class="ruby-identifier">parent</span> <span class="ruby-keyword">and</span> <span class="ruby-identifier">np</span>.<span class="ruby-identifier">parent</span>.<span class="ruby-identifier">node_type</span> <span class="ruby-operator">==</span> <span class="ruby-value">:element</span>
<span class="ruby-identifier">node_idx</span> <span class="ruby-operator"><<</span> <span class="ruby-identifier">np</span>.<span class="ruby-identifier">parent</span>.<span class="ruby-identifier">index</span>( <span class="ruby-identifier">np</span> )
<span class="ruby-identifier">np</span> = <span class="ruby-identifier">np</span>.<span class="ruby-identifier">parent</span>
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">new_arry</span> <span class="ruby-operator"><<</span> [ <span class="ruby-identifier">node_idx</span>.<span class="ruby-identifier">reverse</span>, <span class="ruby-identifier">node</span> ]
}
<span class="ruby-identifier">ordered</span> = <span class="ruby-identifier">new_arry</span>.<span class="ruby-identifier">sort_by</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">index</span>, <span class="ruby-identifier">node</span><span class="ruby-operator">|</span>
<span class="ruby-keyword">if</span> <span class="ruby-identifier">order</span> <span class="ruby-operator">==</span> <span class="ruby-value">:forward</span>
<span class="ruby-identifier">index</span>
<span class="ruby-keyword">else</span>
<span class="ruby-operator">-</span><span class="ruby-identifier">index</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">ordered</span>.<span class="ruby-identifier">collect</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">_index</span>, <span class="ruby-identifier">node</span><span class="ruby-operator">|</span>
<span class="ruby-identifier">node</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span></pre>
</div>
</div>
</div>
<div id="method-i-step" class="method-detail ">
<div class="method-heading">
<span class="method-name">step</span><span
class="method-args">(path_stack, any_type: :element, order: :forward) { || ... }</span>
<span class="method-click-advice">click to toggle source</span>
</div>
<div class="method-description">
<div class="method-source-code" id="step-source">
<pre><span class="ruby-comment"># File lib/rexml/xpath_parser.rb, line 435</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">step</span>(<span class="ruby-identifier">path_stack</span>, <span class="ruby-value">any_type:</span> <span class="ruby-value">:element</span>, <span class="ruby-value">order:</span> <span class="ruby-value">:forward</span>)
<span class="ruby-identifier">nodesets</span> = <span class="ruby-keyword">yield</span>
<span class="ruby-keyword">begin</span>
<span class="ruby-identifier">enter</span>(<span class="ruby-value">:step</span>, <span class="ruby-identifier">path_stack</span>, <span class="ruby-identifier">nodesets</span>) <span class="ruby-keyword">if</span> <span class="ruby-ivar">@debug</span>
<span class="ruby-identifier">nodesets</span> = <span class="ruby-identifier">node_test</span>(<span class="ruby-identifier">path_stack</span>, <span class="ruby-identifier">nodesets</span>, <span class="ruby-value">any_type:</span> <span class="ruby-identifier">any_type</span>)
<span class="ruby-keyword">while</span> <span class="ruby-identifier">path_stack</span>[<span class="ruby-value">0</span>] <span class="ruby-operator">==</span> <span class="ruby-value">:predicate</span>
<span class="ruby-identifier">path_stack</span>.<span class="ruby-identifier">shift</span> <span class="ruby-comment"># :predicate</span>
<span class="ruby-identifier">predicate_expression</span> = <span class="ruby-identifier">path_stack</span>.<span class="ruby-identifier">shift</span>.<span class="ruby-identifier">dclone</span>
<span class="ruby-identifier">nodesets</span> = <span class="ruby-identifier">evaluate_predicate</span>(<span class="ruby-identifier">predicate_expression</span>, <span class="ruby-identifier">nodesets</span>)
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">if</span> <span class="ruby-identifier">nodesets</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">==</span> <span class="ruby-value">1</span>
<span class="ruby-identifier">ordered_nodeset</span> = <span class="ruby-identifier">nodesets</span>[<span class="ruby-value">0</span>]
<span class="ruby-keyword">else</span>
<span class="ruby-identifier">raw_nodes</span> = []
<span class="ruby-identifier">nodesets</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">nodeset</span><span class="ruby-operator">|</span>
<span class="ruby-identifier">nodeset</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">node</span><span class="ruby-operator">|</span>
<span class="ruby-keyword">if</span> <span class="ruby-identifier">node</span>.<span class="ruby-identifier">respond_to?</span>(<span class="ruby-value">:raw_node</span>)
<span class="ruby-identifier">raw_nodes</span> <span class="ruby-operator"><<</span> <span class="ruby-identifier">node</span>.<span class="ruby-identifier">raw_node</span>
<span class="ruby-keyword">else</span>
<span class="ruby-identifier">raw_nodes</span> <span class="ruby-operator"><<</span> <span class="ruby-identifier">node</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">ordered_nodeset</span> = <span class="ruby-identifier">sort</span>(<span class="ruby-identifier">raw_nodes</span>, <span class="ruby-identifier">order</span>)
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">new_nodeset</span> = []
<span class="ruby-identifier">ordered_nodeset</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">node</span><span class="ruby-operator">|</span>
<span class="ruby-comment"># TODO: Remove duplicated</span>
<span class="ruby-identifier">new_nodeset</span> <span class="ruby-operator"><<</span> <span class="ruby-constant">XPathNode</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">node</span>, <span class="ruby-value">position:</span> <span class="ruby-identifier">new_nodeset</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">+</span> <span class="ruby-value">1</span>)
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">new_nodeset</span>
<span class="ruby-keyword">ensure</span>
<span class="ruby-identifier">leave</span>(<span class="ruby-value">:step</span>, <span class="ruby-identifier">path_stack</span>, <span class="ruby-identifier">new_nodeset</span>) <span class="ruby-keyword">if</span> <span class="ruby-ivar">@debug</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span></pre>
</div>
</div>
</div>
<div id="method-i-strict-3F" class="method-detail ">
<div class="method-heading">
<span class="method-name">strict?</span><span
class="method-args">()</span>
<span class="method-click-advice">click to toggle source</span>
</div>
<div class="method-description">
<div class="method-source-code" id="strict-3F-source">
<pre><span class="ruby-comment"># File lib/rexml/xpath_parser.rb, line 148</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">strict?</span>
<span class="ruby-ivar">@strict</span>
<span class="ruby-keyword">end</span></pre>
</div>
</div>
</div>
<div id="method-i-trace" class="method-detail ">
<div class="method-heading">
<span class="method-name">trace</span><span
class="method-args">(*args)</span>
<span class="method-click-advice">click to toggle source</span>
</div>
<div class="method-description">
<div class="method-source-code" id="trace-source">
<pre><span class="ruby-comment"># File lib/rexml/xpath_parser.rb, line 624</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">trace</span>(<span class="ruby-operator">*</span><span class="ruby-identifier">args</span>)
<span class="ruby-identifier">indent</span> = <span class="ruby-string">" "</span> <span class="ruby-operator">*</span> <span class="ruby-ivar">@nest</span>
<span class="ruby-constant">PP</span>.<span class="ruby-identifier">pp</span>(<span class="ruby-identifier">args</span>, <span class="ruby-string">""</span>).<span class="ruby-identifier">each_line</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">line</span><span class="ruby-operator">|</span>
<span class="ruby-identifier">puts</span>(<span class="ruby-node">"#{indent}#{line}"</span>)
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span></pre>
</div>
</div>
</div>
<div id="method-i-unnode" class="method-detail ">
<div class="method-heading">
<span class="method-name">unnode</span><span
class="method-args">(nodeset) { |unnoded| ... }</span>
<span class="method-click-advice">click to toggle source</span>
</div>
<div class="method-description">
<div class="method-source-code" id="unnode-source">
<pre><span class="ruby-comment"># File lib/rexml/xpath_parser.rb, line 944</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">unnode</span>(<span class="ruby-identifier">nodeset</span>)
<span class="ruby-identifier">each_unnode</span>(<span class="ruby-identifier">nodeset</span>).<span class="ruby-identifier">collect</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">unnoded</span><span class="ruby-operator">|</span>
<span class="ruby-identifier">unnoded</span> = <span class="ruby-keyword">yield</span>(<span class="ruby-identifier">unnoded</span>) <span class="ruby-keyword">if</span> <span class="ruby-identifier">block_given?</span>
<span class="ruby-identifier">unnoded</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span></pre>
</div>
</div>
</div>
<div id="method-i-value_type" class="method-detail ">
<div class="method-heading">
<span class="method-name">value_type</span><span
class="method-args">(value)</span>
<span class="method-click-advice">click to toggle source</span>
</div>
<div class="method-description">
<div class="method-source-code" id="value_type-source">
<pre><span class="ruby-comment"># File lib/rexml/xpath_parser.rb, line 871</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">value_type</span>(<span class="ruby-identifier">value</span>)
<span class="ruby-keyword">case</span> <span class="ruby-identifier">value</span>
<span class="ruby-keyword">when</span> <span class="ruby-keyword">true</span>, <span class="ruby-keyword">false</span>
<span class="ruby-value">:boolean</span>
<span class="ruby-keyword">when</span> <span class="ruby-constant">Numeric</span>
<span class="ruby-value">:number</span>
<span class="ruby-keyword">when</span> <span class="ruby-constant">String</span>
<span class="ruby-value">:string</span>
<span class="ruby-keyword">else</span>
<span class="ruby-identifier">raise</span> <span class="ruby-node">"[BUG] Unexpected value type: <#{value.inspect}>"</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span></pre>
</div>
</div>
</div>
</section>
</section>
</main>
<footer id="validator-badges" role="contentinfo">
<p><a href="https://validator.w3.org/check/referer">Validate</a>
<p>Generated by <a href="https://ruby.github.io/rdoc/">RDoc</a> 6.2.1.1.
<p>Based on <a href="http://deveiate.org/projects/Darkfish-RDoc/">Darkfish</a> by <a href="http://deveiate.org">Michael Granger</a>.
</footer>