[nycphp-talk] simplexml xpath bug ? (long post)
Emmanuel M. Décarie
emm at scriptdigital.com
Thu Aug 9 15:51:22 EDT 2007
Hi there,
I'm not sure if this is the way it’s supposing to work or if this is
a bug. Anyway, here's the problem.
I have to parse a very complex XML document where I need to do a
xpath query against a previous found xpath query.
I use simplexml for that.
For the sake of the discussion, I wrote a script to illustrate the
problem (see below or the attachment). And yes, with this example, I
could use just one xpath query to get the same result. But this is an
example, so bare with me.
Ok let's start.
* What I want to do: *
Do a xpath query against a previous xpath query.
* What happened: *
The second xpath query is made against the whole xml tree instead of
a subset of the tree found by the first xpath query.
* Work-around: *
You have to deference the tree.
* My question *
Clearly, what I see is not what I get when I use var_dump or print_r
against the second xpath query. I wonder if there is a bug here.
Also, why the fragment of XML that I get from the first xpath query
still reference the whole tree.
Thanks!
=========================
* Example: The Script*
$xml = <<<END
<?xml version="1.0" encoding="UTF-8"?>
<world>
<continent name='europe'>
<country name='france'>paris</country>
<country name='uk'>london</country>
</continent>
<continent name='africa'>
<country name='zimbabwe'>harare</country>
<country name='egypt'>cairo</country>
</continent>
</world>
END;
$obj = simplexml_load_string ($xml);
$result = $obj->xpath ('//continent');
echo "----------------\n";
echo "result\n";
echo "----------------\n";
var_dump ($result);
echo "\n\n";
$counter = 0;
foreach ($result as $elem) {
$counter++;
echo "----------------\n";
echo "Counter: $counter\n";
echo "----------------\n";
echo "----------------\n";
echo "elem\n";
echo "----------------\n";
var_dump ($elem);
echo "\n";
echo "----------------\n";
echo "elem->xpath('//country')\n";
echo "----------------\n";
var_dump ($elem->xpath ('//country'));
$elem2 = simplexml_load_string ($elem->asXML ());
echo "----------------\n";
echo "elem2->xpath('//country')\n";
echo "----------------\n";
var_dump ($elem2->xpath ('//country'));
}
* The Result: *
----------------
result
----------------
array(2) {
[0]=>
object(SimpleXMLElement)#2 (2) {
["@attributes"]=>
array(1) {
["name"]=>
string(6) "europe"
}
["country"]=>
array(2) {
[0]=>
string(5) "paris"
[1]=>
string(6) "london"
}
}
[1]=>
object(SimpleXMLElement)#3 (2) {
["@attributes"]=>
array(1) {
["name"]=>
string(6) "africa"
}
["country"]=>
array(2) {
[0]=>
string(6) "harare"
[1]=>
string(5) "cairo"
}
}
}
----------------
Counter: 1
----------------
----------------
elem
----------------
object(SimpleXMLElement)#2 (2) {
["@attributes"]=>
array(1) {
["name"]=>
string(6) "europe"
}
["country"]=>
array(2) {
[0]=>
string(5) "paris"
[1]=>
string(6) "london"
}
}
----------------
elem->xpath('//country')
----------------
array(4) {
[0]=>
object(SimpleXMLElement)#4 (2) {
["@attributes"]=>
array(1) {
["name"]=>
string(6) "france"
}
[0]=>
string(5) "paris"
}
[1]=>
object(SimpleXMLElement)#5 (2) {
["@attributes"]=>
array(1) {
["name"]=>
string(2) "uk"
}
[0]=>
string(6) "london"
}
[2]=>
object(SimpleXMLElement)#6 (2) {
["@attributes"]=>
array(1) {
["name"]=>
string(8) "zimbabwe"
}
[0]=>
string(6) "harare"
}
[3]=>
object(SimpleXMLElement)#7 (2) {
["@attributes"]=>
array(1) {
["name"]=>
string(5) "egypt"
}
[0]=>
string(5) "cairo"
}
}
----------------
elem2->xpath('//country')
----------------
array(2) {
[0]=>
object(SimpleXMLElement)#6 (2) {
["@attributes"]=>
array(1) {
["name"]=>
string(6) "france"
}
[0]=>
string(5) "paris"
}
[1]=>
object(SimpleXMLElement)#5 (2) {
["@attributes"]=>
array(1) {
["name"]=>
string(2) "uk"
}
[0]=>
string(6) "london"
}
}
----------------
Counter: 2
----------------
----------------
elem
----------------
object(SimpleXMLElement)#3 (2) {
["@attributes"]=>
array(1) {
["name"]=>
string(6) "africa"
}
["country"]=>
array(2) {
[0]=>
string(6) "harare"
[1]=>
string(5) "cairo"
}
}
----------------
elem->xpath('//country')
----------------
array(4) {
[0]=>
object(SimpleXMLElement)#5 (2) {
["@attributes"]=>
array(1) {
["name"]=>
string(6) "france"
}
[0]=>
string(5) "paris"
}
[1]=>
object(SimpleXMLElement)#6 (2) {
["@attributes"]=>
array(1) {
["name"]=>
string(2) "uk"
}
[0]=>
string(6) "london"
}
[2]=>
object(SimpleXMLElement)#4 (2) {
["@attributes"]=>
array(1) {
["name"]=>
string(8) "zimbabwe"
}
[0]=>
string(6) "harare"
}
[3]=>
object(SimpleXMLElement)#8 (2) {
["@attributes"]=>
array(1) {
["name"]=>
string(5) "egypt"
}
[0]=>
string(5) "cairo"
}
}
----------------
elem2->xpath('//country')
----------------
array(2) {
[0]=>
object(SimpleXMLElement)#7 (2) {
["@attributes"]=>
array(1) {
["name"]=>
string(8) "zimbabwe"
}
[0]=>
string(6) "harare"
}
[1]=>
object(SimpleXMLElement)#4 (2) {
["@attributes"]=>
array(1) {
["name"]=>
string(5) "egypt"
}
[0]=>
string(5) "cairo"
}
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: simplexml_xpath_example.php
Type: text/php
Size: 1133 bytes
Desc: not available
URL: <http://lists.nyphp.org/pipermail/talk/attachments/20070809/b923150b/attachment.bin>
-------------- next part --------------
More information about the talk
mailing list