SimpleXMLElement->xpath

(no version information, might be only in CVS)

SimpleXMLElement->xpath --  Runs Xpath query on XML data

Description

array SimpleXMLElement->xpath ( string path )

The xpath method searches the SimpleXML node for children matching the Xpath path. It always returns an array of SimpleXMLElement objects.

Пример 1. Xpath

<?php
$string
= <<<XML
<a>
 <b>
  <c>text</c>
  <c>stuff</c>
 </b>
 <d>
  <c>code</c>
 </d>
</a>
XML;

$xml = simplexml_load_string($string);

/* Search for <a><b><c> */
$result = $xml->xpath('/a/b/c');

while(list( ,
$node) = each($result)) {
   echo
'/a/b/c: ',$node,"\n";
}

/* Relative paths also work... */
$result = $xml->xpath('b/c');

while(list( ,
$node) = each($result)) {
   echo
'b/c: ',$node,"\n";
}
?>

This script will display:

/a/b/c: text
/a/b/c: stuff
b/c: text
b/c: stuff

Notice that the two results are equal.



SimpleXMLElement->xpath
ron @ rotflol dot cx
29-Mar-2006 09:07
xpath returning references to the parent simplexml object can bite you performance wise when processing large trees.
this bit me big time so looking for a solution I came up with a simple way to speed up the code.

'dereferencing' will yield instant results, code will be lighting fast.
sacrifice is losing the reference to the parent object, for simple read-only operation this should be ok.

<?php
$data
= 'data.xml';
$rs = simplexml_load_file($data);
foreach(
$rs->xpath('//row') as $rsrow){
  
// 'derefence' into a seperate xml tree for performance
  
$row = simplexml_load_string($rsrow->asXML());
  
$v = $row->xpath('//field[@name="id"]');

}
?>
drewish at katherinehouse dot com
09-Jan-2006 11:40
here's a simple work-around for the lack of support for default namespaces, just overwrite the xmlns attribute of the root element:
<?php
$xml
= simplexml_load_file('http://example.com/atom_feed.xml');
// hack to work around php 5.0's problems with default namespaces and xpath()
$xml['xmlns'] = '';
// now our queries work:
$titles = $xml->xpath('entry/title');
foreach ((array)
$titles as $title) {
   print
"$title\n";
}
?>
Hugh
18-Dec-2005 03:23
Note that this function does not ALWAYS return an array. It seems that if the specified path is not found in the document, it will return false. You need to check for the false value before using foreach, if you wish to avoid a warning (and often to handle errors or control program flow in this situation).
retardis at gmail dot com
24-Aug-2005 01:21
Xpath actually returns an array full of references to elements in the parent SimpleXML object. Therefore, in addition to preserving attributes, you can actually modify them and the result will be reflected in the parent.

Example:

<?php

$xml_str
= <<<END
<a>
   <b attr="foo"/>
</a>
END;

$xml = simplexml_load_string ($xml_str);
$result = $xml->xpath ('/a/b'); // returns an array with one element
$result[0]['attr'] = 'bar';
print
$xml->asXML ();
?>

Outputs:
<a>
   <b attr="bar"/>
</a>
drewish at katherinehouse dot com
10-Jul-2005 06:16
xpath() can also be used to select elements by their attributes. For a good XPath reference check out: http://www.w3schools.com/xpath/xpath_syntax.asp

<?php
$string
= <<<XML
<sizes>
   <size label="Square" width="75" height="75" />
   <size label="Thumbnail" width="100" height="62" />
   <size label="Small" width="112" height="69" />
   <size label="Large" width="112" height="69" />
</sizes>
XML;

$xml = simplexml_load_string($string);
$result = $xml->xpath("//size[@label='Large']");

// print the first (and only) member of the array
echo $result[0]->asXml();
?>

The script would print:
<size label="Large" width="112" height="69"/>
nelson dot menezes at yahoo dot co dot uk
16-Feb-2005 01:56
Regarding the note about the return of this function "not retaining tag attributes". This is not true at all (PHP 5.0.3); The attributes are kept for each member of the array returned. So this:

<a>
  <b value="1">xxx1</b>
  <b value="2">xxx2</b>
</a>

An xpath of "/a/b" would return an array with two SimpleXMLElements; each can have their tag properties read like so:

$array_element['value']
dummyusr at hm dot com
26-Nov-2004 12:00
well after testing my conclusion, if you are not interested in namespaces, is:

<?
$sxmltxt
=file_get_contents($url);
$sxmltxt=str_replace("xmlns=","a=",$sxmltxt);
$xmltxt=simplexml_load_string($sxmltxt);
?>

then <? $xmltxt->xpath("//node"); ?> will work
not getting that void array
tyler.bell[at]oxarchdigital[dot]com
03-Sep-2004 08:53
Note: xpath currently (5.0) does not work with xml documents that employ default namespaces, but a fix should be added via registerXPathNamespace() in 5.1. See http://blog.bitflux.ch/p1746.html for more info.
matt@roughest[d0t]net
03-Sep-2004 12:17
This may be obvious, but in case you're wondering, the array resulting from the xpath() operation doesn't retain any of the nodes' attributes.

In other words, it won't return any of the tags' attributes

<SimpleXMLElement->childrensimplexml_import_dom>
 Last updated: Tue, 15 Nov 2005