In a nuthsell, SimpleXMl has two things broken:
1. Elements that represent “emtpy” tags evaluate to false. This is weird design.
2. Other elements sometimes evaluate to false due to bugs.
I covered problem #1 in the previous post. This post is about #2.
Unfortunately, due to bugs in the SimpleXML parser, a non-empty element may evaluate to false. No version I tested is completely bug-free, and the difference between correct and incorrect behavior may be as subtle as adding a space outside the element in question.
The code I use for testing is along these lines:
$xml = $xml = simplexml_load_string($text); $node = $xml->xpath($xpath)[0]; if ($node) echo "Evaluates to true!"; else echo "Evaluates to false!";
Here are the test results:
$text | $xpath | Result | Boolean value |
---|---|---|---|
<root><b>text</b></root> | /root/b | <b>text</b> | PHP 5.4.4 – true PHP 5.4.45 – true PHP 5.6.15 – true |
<root><a/><b>text</b></root> | /root/b | <b>text</b> | PHP 5.4.4 – false PHP 5.4.45 – true PHP 5.6.15 – true |
<root><a/><b>text</b> </root> note extra space before “</root>” |
/root/b | <b>text</b> | PHP 5.4.4 – false PHP 5.4.45 – false PHP 5.6.15 – true |
<x:root xmlns:x=”urn:q”><a /></x:root> same as the first one, only with a namespace |
/x:root | <?xml version=”1.0″?> <x:root xmlns:x=”urn:q”><a/></x:root> |
PHP 5.4.4 – true PHP 5.4.45 – true PHP 5.6.15 – true |
<x:root xmlns:x=”urn:q”><x:a /></x:root> same as previous, but using <x:a /> instead of lt;a /> |
/x:root | <?xml version=”1.0″?> <x:root xmlns:x=”urn:q”><x:a/></x:root> |
PHP 5.4.4 – false PHP 5.4.45 – false PHP 5.6.15 – false |
<x:root xmlns:x=”urn:q”><x:b>text</x:b></x:root> | /x:root | <?xml version=”1.0″?> <x:root xmlns:x=”urn:q”><x:b>text</x:b></x:root> |
PHP 5.4.4 – false PHP 5.4.45 – false PHP 5.6.15 – false |
I believe evaluating non-null objects to false was not a good idea in the first place, but worse yet, PHP cannot really do it right, so the result of if ($node) check is never reliable.