
{"id":1881,"date":"2016-01-02T21:59:48","date_gmt":"2016-01-03T02:59:48","guid":{"rendered":"http:\/\/www.ikriv.com\/blog\/?p=1881"},"modified":"2016-01-02T21:59:48","modified_gmt":"2016-01-03T02:59:48","slug":"php-simplexml-is-broken-part-2","status":"publish","type":"post","link":"https:\/\/ikriv.com\/blog\/?p=1881","title":{"rendered":"PHP SimpleXml is Broken: Part 2"},"content":{"rendered":"<p>In a nuthsell, SimpleXMl has two things broken:<\/p>\n<p>1. Elements that represent &#8220;emtpy&#8221; tags evaluate to <b>false<\/b>. This is weird design.<br \/>\n2. Other elements sometimes evaluate to <b>false<\/b> due to bugs.<\/p>\n<p>I covered problem #1 in the <a href=\"http:\/\/www.ikriv.com\/blog\/?p=1856\">previous post<\/a>. This post is about #2.<\/p>\n<p>Unfortunately, due to bugs in the SimpleXML parser, a non-empty element may evaluate to <b>false<\/b>. No version I tested is completely bug-free, and the difference between correct and incorrect behavior may be as subtle as adding a space <b>outside<\/b> the element in question.<\/p>\n<p>The code I use for testing is along these lines:<\/p>\n<p><code><\/p>\n<pre>$xml = $xml = simplexml_load_string($text);\n$node = $xml->xpath($xpath)[0];\n<b>if<\/b> ($node) echo \"Evaluates to true!\"; <b>else<\/b> echo \"Evaluates to false!\";<\/pre>\n<p><\/code><\/p>\n<p>Here are the test results:<\/p>\n<table border=\"1\" cellspacing=\"0\" cellpadding=\"5\">\n<tr>\n<th>$text<\/th>\n<th>$xpath<\/th>\n<th>Result<\/th>\n<th>Boolean value<\/th>\n<\/tr>\n<tr>\n<td>&lt;root&gt;&lt;b&gt;text&lt;\/b&gt;&lt;\/root&gt;<\/td>\n<td>\/root\/b<\/td>\n<td>&lt;b&gt;text&lt;\/b&gt;<\/td>\n<td>PHP 5.4.4 &#8211; true<br \/>\nPHP 5.4.45 &#8211; true<br \/>\nPHP 5.6.15 &#8211; true<\/td>\n<\/tr>\n<tr>\n<td>&lt;root&gt;&lt;a\/&gt;&lt;b&gt;text&lt;\/b&gt;&lt;\/root&gt;<\/td>\n<td>\/root\/b<\/td>\n<td>&lt;b&gt;text&lt;\/b&gt;<\/td>\n<td><font color=\"red\">PHP 5.4.4 &#8211; false<\/font><br \/>\nPHP 5.4.45 &#8211; true<br \/>\nPHP 5.6.15 &#8211; true<\/td>\n<\/tr>\n<tr>\n<td>&lt;root&gt;&lt;a\/&gt;&lt;b&gt;text&lt;\/b&gt; &lt;\/root&gt;<br \/>\n<font color=\"gray\"><i>note extra space before<\/i> &#8220;&lt;\/root&gt;&#8221;<\/font><\/td>\n<td>\/root\/b<\/td>\n<td>&lt;b&gt;text&lt;\/b&gt;<\/td>\n<td><font color=\"red\">PHP 5.4.4 &#8211; false<br \/>\nPHP 5.4.45 &#8211; false<\/font><br \/>\nPHP 5.6.15 &#8211; true<\/td>\n<\/tr>\n<tr>\n<td>&lt;x:root xmlns:x=&#8221;urn:q&#8221;&gt;&lt;a \/&gt;&lt;\/x:root&gt;<br \/>\n<font color=\"gray\"><i>same as the first one, only with a namespace<\/i><\/font><\/td>\n<td>\/x:root<\/td>\n<td>&lt;?xml version=&#8221;1.0&#8243;?&gt;<br \/>\n&lt;x:root xmlns:x=&#8221;urn:q&#8221;&gt;&lt;a\/&gt;&lt;\/x:root&gt;<\/td>\n<td>PHP 5.4.4 &#8211; true<br \/>\nPHP 5.4.45 &#8211; true<br \/>\nPHP 5.6.15 &#8211; true<\/td>\n<\/tr>\n<tr>\n<td>&lt;x:root xmlns:x=&#8221;urn:q&#8221;&gt;&lt;x:a \/&gt;&lt;\/x:root&gt;<br \/>\n<font color=\"gray\"><i>same as previous, but using &lt;x:a \/&gt; instead of lt;a \/&gt;<\/i><\/font><\/td>\n<td>\/x:root<\/td>\n<td>&lt;?xml version=&#8221;1.0&#8243;?&gt;<br \/>\n&lt;x:root xmlns:x=&#8221;urn:q&#8221;&gt;&lt;x:a\/&gt;&lt;\/x:root&gt;<\/td>\n<td><font color=\"red\">PHP 5.4.4 &#8211; false<br \/>\nPHP 5.4.45 &#8211; false<br \/>\nPHP 5.6.15 &#8211; false<\/font><\/td>\n<\/tr>\n<tr>\n<td>&lt;x:root xmlns:x=&#8221;urn:q&#8221;&gt;&lt;x:b&gt;text&lt;\/x:b&gt;&lt;\/x:root&gt;<\/td>\n<td>\/x:root<\/td>\n<td>&lt;?xml version=&#8221;1.0&#8243;?&gt;<br \/>\n&lt;x:root xmlns:x=&#8221;urn:q&#8221;&gt;&lt;x:b&gt;text&lt;\/x:b&gt;&lt;\/x:root&gt;<\/td>\n<td><font color=\"red\">PHP 5.4.4 &#8211; false<br \/>\nPHP 5.4.45 &#8211; false<br \/>\nPHP 5.6.15 &#8211; false<\/font><\/td>\n<\/tr>\n<\/table>\n<p>I believe evaluating non-null objects to <b>false<\/b> was not a good idea in the first place, but worse yet, PHP cannot really do it right, so the result of <b>if ($node)<\/b> check is never reliable.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In a nuthsell, SimpleXMl has two things broken: 1. Elements that represent &#8220;emtpy&#8221; tags evaluate to false. This is weird design. 2. Other elements sometimes evaluate to false due to <a href=\"https:\/\/ikriv.com\/blog\/?p=1881\" class=\"more-link\">[&hellip;]<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"Layout":"","footnotes":""},"categories":[5,15],"tags":[],"class_list":["entry","author-ikriv","post-1881","post","type-post","status-publish","format-standard","category-dev","category-webdev"],"_links":{"self":[{"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1881","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1881"}],"version-history":[{"count":0,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1881\/revisions"}],"wp:attachment":[{"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1881"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1881"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1881"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}