<?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>Dimuthu's Blog &#187; xpath</title>
	<atom:link href="http://www.dimuthu.org/catagory/xml/xpath-xml/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.dimuthu.org</link>
	<description>Waiting for your comments</description>
	<lastBuildDate>Wed, 07 Jul 2010 12:42:52 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
<image>
  <link>http://www.dimuthu.org</link>
  <url>http://www.dimuthu.org/favicon.ico</url>
  <title>Dimuthu's Blog</title>
</image>
		<item>
		<title>XPath in SimpleXML</title>
		<link>http://www.dimuthu.org/blog/2008/09/30/xpath-in-simplexml/</link>
		<comments>http://www.dimuthu.org/blog/2008/09/30/xpath-in-simplexml/#comments</comments>
		<pubDate>Tue, 30 Sep 2008 17:40:03 +0000</pubDate>
		<dc:creator>dimuthu</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[xml]]></category>
		<category><![CDATA[xpath]]></category>
		<category><![CDATA[simplexml]]></category>

		<guid isPermaLink="false">http://www.dimuthu.org/?p=416</guid>
		<description><![CDATA[SimpleXML as it name imply, is a very simple API to traverse XML implemented specially in PHP language. It is very similar to the XPath, but since it has more PHP friendly syntax PHP developers really like to use it. As an Example for this XML: &#60;dwml&#62; &#60;data&#62; &#60;location&#62; &#60;location-key&#62;point1&#60;/location-key&#62; &#60;point latitude="37.39" longitude="-122.07"&#62;&#60;/point&#62; &#60;/location&#62; &#60;/data&#62; [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://php.net/simplexml">SimpleXML</a> as it name imply, is a very simple API to traverse XML implemented specially in PHP language. It is very similar to the XPath, but since it has more PHP friendly syntax PHP developers really like to use it.<br />
As an Example for this XML:</p>
<pre class="xml"><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;dwml<span style="font-weight: bold; color: black;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;data<span style="font-weight: bold; color: black;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;location<span style="font-weight: bold; color: black;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;location-key<span style="font-weight: bold; color: black;">&gt;</span></span></span>point1<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/location-key<span style="font-weight: bold; color: black;">&gt;</span></span></span>
      	<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;point</span> <span style="color: #000066;">latitude</span>=<span style="color: #ff0000;">"37.39"</span> <span style="color: #000066;">longitude</span>=<span style="color: #ff0000;">"-122.07"</span><span style="font-weight: bold; color: black;">&gt;</span></span><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/point<span style="font-weight: bold; color: black;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/location<span style="font-weight: bold; color: black;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/data<span style="font-weight: bold; color: black;">&gt;</span></span></span>
  .....
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/dwml<span style="font-weight: bold; color: black;">&gt;
</span></span></span></pre>
<p>XPATH Query to take the latitude in more general way</p>
<pre><em>/dwml/data/location/point/@latitude
</em></pre>
<p>Where as with simple XML it is just a familiar PHP statement,</p>
<pre><em>$simplexml-&gt;data-&gt;location-&gt;point-&gt;attributes()-&gt;latitude</em></pre>
<p>Anyway still you can use the xpath inside your simplexml code. You can execute xpath queries by calling xpath function from any SimpleXMLEelment. It will return an array of SimpleXMLElement that match your query. So for the above example your XPath query would be something  like this,</p>
<pre class="php"><span style="color: #0000ff;">$simplexml</span>= <span style="font-weight: bold; color: #000000;">new</span> SimpleXMLElement<span style="color: #66cc66;">(</span><span style="color: #0000ff;">$xml</span><span style="color: #66cc66;">)</span>;
<span style="color: #0000ff;">$lats</span> =  <span style="color: #0000ff;">$simplexml</span>-&gt;<span style="color: #006600;">xpath</span><span style="color: #66cc66;">(</span><span style="color: #ff0000;">'/dwml/data/location/point/@latitude'</span><span style="color: #66cc66;">)</span>;
<a href="http://www.php.net/echo"><span style="color: #000066;">echo</span></a> <span style="color: #0000ff;">$lats</span><span style="color: #66cc66;">[</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">]</span>;</pre>
<p>This simplicity allows you to choose between these two methods interchangeably as best fit per your application. Here are some cases that I think use of XPath is more easy.</p>
<p><strong>Ability to use of XPath shorthand</strong><br />
Take the above example XML it self. If there is only one attribute named &#8216;latitude&#8217; throughout the XML you can call that value by</p>
<pre>//@latitude</pre>
<p><strong>If XML node name or attribute name contains characters like &#8216;-&#8217; which are not allowed in PHP for variable names</strong><br />
In the example if you want to access the value inside &#8216;location-key&#8217; node using simplexml it would be like,</p>
<pre><a href="http://www.php.net/echo"><span style="color: #000066;">echo</span></a> <span style="color: #0000ff;">$simplexml</span>-&gt;<span style="color: #006600;">data</span>-&gt;<span style="color: #006600;">location</span>-&gt;<span style="color: #006600;">location-key</span>;</pre>
<p>This will not give you the expected result as PHP will try to think &#8216;location&#8217; and &#8216;key&#8217; as two taken in &#8216;location-key&#8217;. So this particular code can be replaced with the xpath function.</p>
<pre class="php"><span style="color: #0000ff;">$keys</span> =  <span style="color: #0000ff;">$simplexml</span>-&gt;<span style="color: #006600;">xpath</span><span style="color: #66cc66;">(</span><span style="color: #ff0000;">'/dwml/data/location/location-key'</span><span style="color: #66cc66;">)</span>;
<a href="http://www.php.net/echo"><span style="color: #000066;">echo</span></a> <span style="color: #0000ff;">$keys</span><span style="color: #66cc66;">[</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">]</span>;</pre>
<p><strong>You want to iterate through node with a same name in an XML</strong></p>
<p>If the nodes which we want to iterate is in organized positions  in an XML (like the one in following) both approaches can be used with same easiness.</p>
<pre class="xml"><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;root<span style="font-weight: bold; color: black;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;mynode<span style="font-weight: bold; color: black;">&gt;</span></span></span>value1<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/mynode<span style="font-weight: bold; color: black;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;mynode<span style="font-weight: bold; color: black;">&gt;</span></span></span>value2<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/mynode<span style="font-weight: bold; color: black;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;mynode<span style="font-weight: bold; color: black;">&gt;</span></span></span>value3<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/mynode<span style="font-weight: bold; color: black;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;mynode<span style="font-weight: bold; color: black;">&gt;</span></span></span>value4<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/mynode<span style="font-weight: bold; color: black;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;mynode<span style="font-weight: bold; color: black;">&gt;</span></span></span>value5<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/mynode<span style="font-weight: bold; color: black;">&gt;</span></span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/root<span style="font-weight: bold; color: black;">&gt;</span></span></span></pre>
<p>But how if the &#8216;mynode&#8217; was in different locations in an XML like this,</p>
<pre class="xml"><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;root<span style="font-weight: bold; color: black;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;anothernode<span style="font-weight: bold; color: black;">&gt;</span></span></span>
     <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;mynode<span style="font-weight: bold; color: black;">&gt;</span></span></span>value1<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/mynode<span style="font-weight: bold; color: black;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/anothernode<span style="font-weight: bold; color: black;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;anotheranothernode<span style="font-weight: bold; color: black;">&gt;</span></span></span>
     <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;anotheranotheranothernode<span style="font-weight: bold; color: black;">&gt;</span></span></span>
       <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;mynode<span style="font-weight: bold; color: black;">&gt;</span></span></span>value2<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/mynode<span style="font-weight: bold; color: black;">&gt;</span></span></span>
     <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/anotheranotheranothernode<span style="font-weight: bold; color: black;">&gt;</span></span></span>
     <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;mynode<span style="font-weight: bold; color: black;">&gt;</span></span></span>value3<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/mynode<span style="font-weight: bold; color: black;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/anotheranothernode<span style="font-weight: bold; color: black;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;<strong>mynode</strong><span style="font-weight: bold; color: black;">&gt;</span></span></span>value4<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/mynode<span style="font-weight: bold; color: black;">&gt;</span></span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/root<span style="font-weight: bold; color: black;">&gt;</span></span></span></pre>
<p>You can iterate all the &#8216;mynode&#8217; nodes with the following xpath query.</p>
<pre>//mynode</pre>
<p>Note that this case can be handled easily in DOM with the getElementsByName.</p>
<p><strong>To use the power of XPath functions and Axes</strong><br />
You can use the XPath functions like last(), position() and even string manipulation functions like substring() in a XPath statement.<br />
For an example in the above example, if you want only take the value of last &#8216;mynode&#8217; just use this expression</p>
<pre>//mynode[last()]</pre>
<p>And you can use the power of axes in Xpath Queries. If you want to iterate all the ancestors from current node just use this query</p>
<pre>'ancestor::*'</pre>
<p><strong>Access elements with different namespaces</strong></p>
<pre class="xml"><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;saleItems<span style="font-weight: bold; color: black;">&gt;</span></span></span>
   <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;ns1:car</span> xmlns:ns1=<span style="color: #ff0000;">"http:/toyota.xxx.com"</span><span style="font-weight: bold; color: black;">&gt;</span></span>$3000<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/ns1:car<span style="font-weight: bold; color: black;">&gt;</span></span></span>
   <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;ns2:car</span> xmlns:ns2=<span style="color: #ff0000;">"http:/suziki.rrr.com"</span><span style="font-weight: bold; color: black;">&gt;</span></span>$4000<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/ns2:car<span style="font-weight: bold; color: black;">&gt;</span></span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/saleItems<span style="font-weight: bold; color: black;">&gt;</span></span></span></pre>
<p>You want to extract the cars from simpleXML. You can do this by following code.</p>
<pre class="php"><span style="color: #0000ff;">$simplexml</span>= <span style="font-weight: bold; color: #000000;">new</span> SimpleXMLElement<span style="color: #66cc66;">(</span><span style="color: #0000ff;">$xml</span><span style="color: #66cc66;">)</span>;
<span style="color: #0000ff;">$ns1_childs</span> = <span style="color: #0000ff;">$simplexml</span>-&gt;<span style="color: #006600;">children</span><span style="color: #66cc66;">(</span><span style="color: #ff0000;">"http:/toyota.xxx.com"</span><span style="color: #66cc66;">)</span>;
<a href="http://www.php.net/echo"><span style="color: #000066;">echo</span></a> <span style="color: #0000ff;">$ns1_childs</span>-&gt;<span style="color: #006600;">car</span>;

<span style="color: #0000ff;">$ns2_childs</span> = <span style="color: #0000ff;">$simplexml</span>-&gt;<span style="color: #006600;">children</span><span style="color: #66cc66;">(</span><span style="color: #ff0000;">"http:/suziki.rrr.com"</span><span style="color: #66cc66;">)</span>;
<a href="http://www.php.net/echo"><span style="color: #000066;">echo</span></a> <span style="color: #0000ff;">$ns2_childs</span>-&gt;<span style="color: #006600;">car</span>;</pre>
<p>Every time you access a different namespace you have to call the children method with the namespace as an argument.</p>
<p>If you use XPath approach, you first register the namespces with an prefix and just use those prefix in your XPath queries.</p>
<pre class="php"><span style="color: #0000ff;">$simplexml</span>= <span style="font-weight: bold; color: #000000;">new</span> SimpleXMLElement<span style="color: #66cc66;">(</span><span style="color: #0000ff;">$xml</span><span style="color: #66cc66;">)</span>;

<span style="color: #0000ff;">$simplexml</span>-&gt;<span style="color: #006600;">registerXPathNamespace</span><span style="color: #66cc66;">(</span><span style="color: #ff0000;">"p1"</span>, <span style="color: #ff0000;">"http:/toyota.xxx.com"</span><span style="color: #66cc66;">)</span>;
<span style="color: #0000ff;">$simplexml</span>-&gt;<span style="color: #006600;">registerXPathNamespace</span><span style="color: #66cc66;">(</span><span style="color: #ff0000;">"p2"</span>, <span style="color: #ff0000;">"http:/suziki.rrr.com"</span><span style="color: #66cc66;">)</span>;

<span style="color: #0000ff;">$toyota_cars</span> = <span style="color: #0000ff;">$simplexml</span>-&gt;<span style="color: #006600;">xpath</span><span style="color: #66cc66;">(</span><span style="color: #ff0000;">'//p1:car'</span><span style="color: #66cc66;">)</span>;
<span style="color: #0000ff;">$suziki_cars</span> = <span style="color: #0000ff;">$simplexml</span>-&gt;<span style="color: #006600;">xpath</span><span style="color: #66cc66;">(</span><span style="color: #ff0000;">'//p2:car'</span><span style="color: #66cc66;">)</span>;

<a href="http://www.php.net/echo"><span style="color: #000066;">echo</span></a> <span style="color: #0000ff;">$toyota_cars</span><span style="color: #66cc66;">[</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">]</span>;
<a href="http://www.php.net/echo"><span style="color: #000066;">echo</span></a> <span style="color: #0000ff;">$suziki_cars</span><span style="color: #66cc66;">[</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">]</span>;</pre>
<p>SimpleXML is simple and powerful in its native form. But whenever it is impossible or difficult to use you don&#8217;t need to go back for tedious DOM or manual string manipulation. You can use the xpath queries to get the work done within the simplexml environment itself.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dimuthu.org/blog/2008/09/30/xpath-in-simplexml/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
	</channel>
</rss>
