<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Cowburn &#187; XPath</title>
	<atom:link href="http://cowburn.info/category/xpath/feed/" rel="self" type="application/rss+xml" />
	<link>http://cowburn.info</link>
	<description>Online storage depot for Peter Cowburn</description>
	<lastBuildDate>Sat, 17 Mar 2012 13:12:56 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Using PHP Functions in XPath Expressions</title>
		<link>http://cowburn.info/2009/10/23/php-funcs-xpath/</link>
		<comments>http://cowburn.info/2009/10/23/php-funcs-xpath/#comments</comments>
		<pubDate>Fri, 23 Oct 2009 20:41:13 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[XPath]]></category>
		<category><![CDATA[DOM]]></category>

		<guid isPermaLink="false">http://cowburn.info/?p=336</guid>
		<description><![CDATA[Disclaimer: this article expects familiarity with using the DOM1 extension and XPath2 expressions. The (currently undocumentednow documented3) DOMXPath::registerPHPFunctions method is available as of PHP 5.3.0 (it was added to the code base back in December 2006) and allows the use of PHP functions (and static methods) within XPath queries to complement the normal set of [...]]]></description>
			<content:encoded><![CDATA[<p>Disclaimer: this article expects familiarity with using the DOM<sup><a href="#fn1" title="footnote 1">1</a></sup> extension and XPath<sup><a href="#fn2" title="footnote 2">2</a></sup> expressions. </p>
<p>The (<del datetime="2009-10-26T14:15:44Z">currently undocumented</del><ins datetime="2009-10-26T14:15:44Z">now documented</ins><sup><a href="#fn3" title="footnote 3">3</a></sup>) <code>DOMXPath::registerPHPFunctions</code> method is available as of PHP 5.3.0 (it was added to the code base back in December 2006) and allows the use of PHP functions (and static methods) within XPath queries to complement the normal set of XPath functions<sup><a href="#fn2" title="footnote 2">2</a></sup>.<span id="more-336"></span></p>
<h3>Description</h3>
<p><code>void <strong>DOMXPath::registerPHPFunctions</strong>  ([ string|array <var>$restrict</var>] )</code></p>
<p>Enables the use of PHP functions as XPath functions.</p>
<h3>Parameters</h3>
<dl>
<dt>restrict</dt>
<dd>
Use this parameter to only allow certain functions to be called from XPath; it can be either a string (a function name) or an array of function names.
</dd>
</dl>
<h3>Return Values</h3>
<p>No value is returned.</p>
<h3>Examples</h3>
<p><strong>Note:</strong> The following examples load a sample XML document called <kbd>book.xml</kbd> with the following contents:</p>
<div class="codecolorer-container xml twitlight moo-highlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><div class="xml codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;UTF-8&quot;</span><span style="color: #000000; font-weight: bold;">?&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;books<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;book<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;title<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>PHP Basics<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/title<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;author<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Jim Smith<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/author<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;author<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Jane Smith<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/author<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/book<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;book<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;title<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>PHP Secrets<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/title<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;author<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Jenny Smythe<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/author<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/book<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;book<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;title<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>XML basics<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/title<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;author<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Joe Black<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/author<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/book<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/books<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></div></div>
<h3 id="ex1">Example #1: Call a PHP function in XPath with <code>php:functionString</code></h3>
<p>This example demonstrates the basic use of <code>DOMXPath::registerPHPFunctions</code> by replicating the <code>substring</code> XPath function. The first thing that needs to be done is to register the <samp>php</samp> namespace with the associated URI <samp>http://php.net/xpath</samp>. Don&#8217;t question it, it just needs to be done!</p>
<p>Next, we call <code>DOMXPath::registerPHPFunctions</code> on our object. If no arguments are used, as in this example, then the range of functions allowed to be called is not restricted—you can call any<sup><a href="#fn4" title="footnote 4">4</a></sup> function from XPath. I would always advise restricting the functions which can be called, see <a href="#ex2" title="Example 2">example 2</a>.</p>
<p>Within our XPath query, we use <code>php:functionString</code> which allows us to name a function and provide some parameters (or indeed, no parameters) to be passed to that function. There are two flavours which can be used here: <code>php:functionString</code> which passes an XML node/attribute as a string and <code>php:function</code> (see <a href="#ex3" title="Example 3">example 3</a>) which passes an array of XML node/attribute objects (in <code>DOMElement</code> / <code>DOMAttr</code> / etc. form) to the function .  In this example the PHP function <a href="http://php.net/substr"><code>substr</code></a> is called, passing along the book&#8217;s title (in string form), an offset of <samp>0</samp> and length of <samp>3</samp>. This returns the first 3 characters of the book&#8217;s title which is then compared to the string <kbd>PHP</kbd> in order to filter our list of books down to those having titles starting with <kbd>PHP</kbd>.</p>
<div class="codecolorer-container php twitlight moo-highlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
<span style="color: #000088;">$dom</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> DOMDocument<span style="color: #339933;">;</span><br />
<span style="color: #000088;">$dom</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">load</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'book.xml'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000088;">$xpath</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> DOMXPath<span style="color: #009900;">&#40;</span><span style="color: #000088;">$dom</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #666666; font-style: italic;">// Register the php: namespace (required)</span><br />
<span style="color: #000088;">$xpath</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">registerNamespace</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;php&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;http://php.net/xpath&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #666666; font-style: italic;">// Register PHP functions (no restrictions)</span><br />
<span style="color: #000088;">$xpath</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">registerPHPFunctions</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #666666; font-style: italic;">// Call substr function on the book title</span><br />
<span style="color: #000088;">$nodes</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$xpath</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'//book[php:functionString(&quot;substr&quot;, title, 0, 3) = &quot;PHP&quot;]'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Found <span style="color: #006699; font-weight: bold;">{$nodes-&gt;length}</span> books starting with 'PHP':<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span><br />
<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$nodes</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$node</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000088;">$title</span> &nbsp;<span style="color: #339933;">=</span> <span style="color: #000088;">$node</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getElementsByTagName</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;title&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">item</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">nodeValue</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #000088;">$author</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$node</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getElementsByTagName</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;author&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">item</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">nodeValue</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;<span style="color: #006699; font-weight: bold;">$title</span> by <span style="color: #006699; font-weight: bold;">$author</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<span style="color: #000000; font-weight: bold;">?&gt;</span></div></div>
<p>The example will output something like:</p>
<div class="codecolorer-container plain twitlight moo-highlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><div class="plain codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Found 2 books starting with 'PHP':<br />
PHP Basics by Jim Smith<br />
PHP Secrets by Jenny Smythe</div></div>
<h3 id="ex2">Example #2: Restricting the functions available to XPath</h3>
<p>To restrict the functions made available to XPath, provide either a string containing the name of the single function that you wish to allow or an array of strings containing function names as the <var>restrict</var> parameter (note: static methods can also be used, e.g. &#8220;<samp>Classname::method</samp>&#8220;).  If functions were added with <var>restrict</var> and a function is called in XPath which is not one of them, an <var>E_WARNING</var> will be raised stating <samp>Not allowed to call handler &#8216;<var>function</var>()&#8217;</samp> (where <var>function</var> is the name of the function that cannot be called).</p>
<div class="codecolorer-container php twitlight moo-highlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
<span style="color: #000088;">$dom</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> DOMDocument<span style="color: #339933;">;</span><br />
<span style="color: #000088;">$dom</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">load</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'book.xml'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000088;">$xpath</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> DOMXPath<span style="color: #009900;">&#40;</span><span style="color: #000088;">$dom</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #666666; font-style: italic;">// Register the php: namespace (required)</span><br />
<span style="color: #000088;">$xpath</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">registerNamespace</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;php&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;http://php.net/xpath&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #666666; font-style: italic;">// Register PHP functions (no restrictions)</span><br />
<span style="color: #000088;">$xpath</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">registerPHPFunctions</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;strtoupper&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #666666; font-style: italic;">// Get first book's title in uppercase</span><br />
<span style="color: #000088;">$title</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$xpath</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">evaluate</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'php:functionString(&quot;strtoupper&quot;, //book[1]/title)'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$title</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #666666; font-style: italic;">// Try a function not in our restrictions list</span><br />
<span style="color: #000088;">$fail</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$xpath</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">evaluate</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'php:functionString(&quot;strtolower&quot;, //book[1]/title)'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">?&gt;</span></div></div>
<p>The example will output something like:</p>
<div class="codecolorer-container plain twitlight moo-highlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><div class="plain codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">PHP BASICS&lt;br /&gt;<br />
&lt;b&gt;Warning&lt;/b&gt;: &nbsp;DOMXPath::evaluate() [&lt;a href='domxpath.evaluate'&gt;domxpath.evaluate&lt;/a&gt;]: Not allowed to call handler 'strtolower()'. in &lt;b&gt;example2.php&lt;/b&gt; on line &lt;b&gt;18&lt;/b&gt;&lt;br /&gt;</div></div>
<h3 id="ex3">Example #3: Passing DOM objects using <code>php:function</code></h3>
<p>Up to now, the examples have both used <code>php:functionString</code>. As mentioned above, instead of passing a string value to the PHP function it is possible to pass along an array of DOM* objects to manipulate them as you please by using <code>php:function</code>.</p>
<div class="codecolorer-container php twitlight moo-highlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
<span style="color: #000088;">$dom</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> DOMDocument<span style="color: #339933;">;</span><br />
<span style="color: #000088;">$dom</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">load</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'book.xml'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000088;">$xpath</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> DOMXPath<span style="color: #009900;">&#40;</span><span style="color: #000088;">$dom</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #666666; font-style: italic;">// Register the php: namespace (required)</span><br />
<span style="color: #000088;">$xpath</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">registerNamespace</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;php&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;http://php.net/xpath&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #666666; font-style: italic;">// Register PHP functions (no restrictions)</span><br />
<span style="color: #000088;">$xpath</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">registerPHPFunctions</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;example3&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">function</span> example3<span style="color: #009900;">&#40;</span><span style="color: #000088;">$nodes</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// Return true if more than one author</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$nodes</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<span style="color: #666666; font-style: italic;">// Filter books with multiple authors</span><br />
<span style="color: #000088;">$books</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$xpath</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'//book[php:function(&quot;example3&quot;, author)]'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Books with multiple authors:<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span><br />
<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$books</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$book</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$book</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getElementsByTagName</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;title&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">item</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">nodeValue</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<span style="color: #000000; font-weight: bold;">?&gt;</span></div></div>
<p>The example will output something like:</p>
<div class="codecolorer-container plain twitlight moo-highlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><div class="plain codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Books with multiple authors:<br />
PHP Basics</div></div>
<h3>Summary</h3>
<p>Just to quickly summarise everything, here is a quick run-down. In PHP, make sure to register the <kbd>php</kbd> namespace (with the URI <kbd>http://php.net/xpath</kbd>) and then register your PHP functions (whether core, extensions or user-defined) or static methods with <code>DOMXPath::registerPHPFunctions</code>. In XPath, use <code>php:functionString</code> or <code>php:function</code> to call the PHP function.</p>
<p>If you have made use of this feature, or want to know more, then do feel free to comment. Thanks for reading.</p>
<h4>Footnotes</h4>
<ol>
<li id="fn1"><a href="http://php.net/dom" title="PHP: DOM">http://php.net/dom</a></li>
<li id="fn2"><a href="http://schlitt.info/opensource/blog/0704_xpath.html" title="XPath overview">http://schlitt.info/opensource/blog/0704_xpath.html</a>
<li id="fn3">The documentation page, <del datetime="2009-10-26T14:15:44Z">when it gets written, will be</del><ins datetime="2009-10-26T14:15:44Z">is</ins> available at <a href="http://php.net/domxpath.registerphpfunctions" title="PHP: DOMXPath::registerPHPFunctions">http://php.net/domxpath.registerphpfunctions</a></li>
<li id="fn4">In truth, some functions are not suitable such as those that return non-scalar values (and cannot be cast to one) which XPath will not understand.</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://cowburn.info/2009/10/23/php-funcs-xpath/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>XPath for CSS classes</title>
		<link>http://cowburn.info/2009/06/15/xpath-css-class/</link>
		<comments>http://cowburn.info/2009/06/15/xpath-css-class/#comments</comments>
		<pubDate>Mon, 15 Jun 2009 19:18:57 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[XPath]]></category>
		<category><![CDATA[contains]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[normalize-space]]></category>
		<category><![CDATA[YQL]]></category>

		<guid isPermaLink="false">http://cowburn.info/?p=203</guid>
		<description><![CDATA[I was playing around with YQL today and was scraping a HTML document (no details, that&#8217;s not the point of this blog entry). Part of the processes meant that I needed to check for a specific CSS class attached to some elements. Easy enough, XPath contains (pardon the pun, see later) some nifty functions which [...]]]></description>
			<content:encoded><![CDATA[<p>I was playing around with <a href="http://developer.yahoo.com/yql/" title="Yahoo! Query Language">YQL</a> today and was scraping a HTML document (no details, that&#8217;s not the point of this blog entry).  Part of the processes meant that I needed to check for a specific CSS class attached to some elements. </p>
<p>Easy enough, XPath contains (pardon the pun, see later) some nifty functions which can act on nodes and their values to be used in conditional checks like I needed. I&#8217;ve been using the technique outlined in this post for a very long while (usually with XPath in PHP) and originally stumbled upon the basic idea from <a href="http://plasmasturm.org/log/444/">How to map CSS selectors to XPath queries</a> (Thanks ever so much!) Today&#8217;s use of it prompted this blog post. <span id="more-203"></span></p>
<p>For example, to grab any <code>li</code> elements with a class of <var>active</var> (and only that one class) out of the document it would be easy enough to use:</p>
<div class="codecolorer-container xpath twitlight moo-highlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><div class="xpath codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">//li[@class=&quot;active&quot;]</div></div>
<p>Now, as I said that will only grab the list items which have that specific class like <code>&lt;li class="active"&gt;</code>.  What if there is more than one class in there, ala <code>&lt;li class="hot active"&gt;</code>? We could use the XPath function <code>contains</code> which looks to see if a string contains another string but that would cause problems (e.g. searching for &#8220;a&#8221; in conjunction with classes like &#8220;active&#8221;, &#8220;nav&#8221;, etc. would result in false positives).</p>
<p>To match any list item with a classes which contains the letter &#8220;a&#8221; can be sought with:</p>
<div class="codecolorer-container xpath twitlight moo-highlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><div class="xpath codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">//li[contains(@class, &quot;a&quot;)]</div></div>
<p>Nearly there, now to work out how to not match false positives.  To do this, we can look for &#8220;<code>[space]a[space]</code>&#8221; with a slightly modified class string (classes at the  start/end of the string wouldn&#8217;t normally have spaces before/after respectively). Whilst we&#8217;re at it, we can <em>normalize</em> the spaces in the class string which converts any number of spaces, tabs, etc. characters into just a single space.</p>
<p>So, to properly get at a class name of &#8220;<var>active</var>&#8221; for all list items, regardless of its position in the class string, the following XPath query can be used.</p>
<div class="codecolorer-container xpath twitlight moo-highlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><div class="xpath codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">//li[contains(concat(&quot; &quot;, normalize-space(@class), &quot; &quot;), &quot; active &quot;)]</div></div>
<p><span class="aside">Note: there are single spaces in the first and last arguments for <code>concat</code>, and on either side of the word <code>active</code></span>.</p>
<p>Just as an observation, the comparable CSS selector to do this would be <code>li[class~="active"]</code> (or the more usual <code>li.active</code>) which would be awesome to use if XPath decided to implement a similar syntax.</p>
]]></content:encoded>
			<wfw:commentRss>http://cowburn.info/2009/06/15/xpath-css-class/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

