SimpleXML and default namespace

It looks like php 5.2.6 has a problem with xpath queries on SimpleXMLElement with a default namespace!

Let’s say your xml file is the following:

<?xml version="1.0"?>
<request name="/do/action" xmlns="mynamespace">
</request>

Let’s say you create a SimpleXMLElement: $sxe = new SimpleXMLElement($xml_string);

Now you want to extract content of ‘name’ parameter in ‘request’ node:

$sxe->xpath('/request[@name]);

This will not return any result because you did not registered your default namespace.
Well let’s do it! First argument is the prefix, second is the namespace:

$sxe->registerXPathNamespace('', 'mynamespace');

If you run again your xpath query, you won’t get any result! Too bad! Looks like a simplexml bug to me.

solution

You must assign a prefix to your namespace when registering it with simplexml, and use it in your xpath query. Let’s say we will use ‘default’, then we should do the following:

$sxe->registerXPathNamespace('', 'mynamespace');
$sxe->xpath('/request[@name]);

Now it works.

Bad news is you need to register xpath namespaces on each SimpleXMLElement on which you’re calling ->xpath() (cf. XPath, SimpleXML and default namespace)

generic solution

A generic solution is given in a user comment on php simplexml documentation page:

$namespaces = $xml->getNamespaces(true);
if(isset($namespaces[""]))  // if you have a default namespace {
// register a prefix for that default namespace:
$xml->registerXPathNamespace("default", $namespaces[""]);
// and use that prefix in all of your xpath expressions:
$xpath_to_document = "//default:document";
} else $xpath_to_document = "//document";
$document = $xml->xpath($xpath_to_document);

sources

Post a Comment

Your email is never published nor shared. You're allow to say what you want...