note 92136 modified in function.simplexml-element-registerXPathNamespace by danbrown

From: Date: Wed, 16 Sep 2009 15:56:54 +0000
Subject: note 92136 modified in function.simplexml-element-registerXPathNamespace by danbrown
References: 1  Groups: php.notes 
Request: Send a blank email to php-notes+get-160701@lists.php.net to get a copy of this message
A problem occurs when the XML document you want to parse does not declare a namespace consistently; sometimes it does declare the namespace, sometimes not. Your XPath queries will fail if you use the ns prefix in your query while it is not declared in the XML (resulting in this error: "SimpleXMLElement::xpath() [simplexmlelement.xpath]: Undefined namespace prefix"). On the other hand the query will also fail if you don't use the prefix if the namespace is declared in the XML (will return an empty result). Since you can only register a namespace prefix for XPath if the namespace is declared (registerXPathNamespace()), the only way to cope with this, is to write the prefix in your XPath queries with a little variable. eg. <?php // get used namespaces $namespaces = $this->simple_xml->getNamespaces(TRUE); // say namespace 'pre:' is not defined consistently // define namespace prefix var for xpath queries $this->ns_prefix = isset($namespaces['pre']) ? 'pre:' : ''; // your xpath queries look like this (section/pre:value or section/value) $res = $this->simple_xml->xpath('section/'. $this->ns_prefix .'value'); ?> It is not an elegant solution but it I couldn't find a better one. (Add a registerNamespace($prefix, $url) method? ;)) --was-- A problem occurs when the XML document you want to parse does not declare a namespace consistently; sometimes it does declare the namespace, sometimes not. Your XPath queries will fail if you use the ns prefix in your query while it is not declared in the XML (resulting in this error: "SimpleXMLElement::xpath() [simplexmlelement.xpath]: Undefined namespace prefix"). On the other hand the query will also fail if you don't use the prefix if the namespace is declared in the XML (will return an empty result). Since you can only register a namespace prefix for XPath if the namespace is declared (registerXPathNamespace()), the only way to cope with this, is to write the prefix in your XPath queries with a little variable. eg. <?php // get used namespaces $namespaces = $this->simple_xml->getNamespaces(TRUE); // say namespace 'pre:' is not defined consistently // define namespace prefix var for xpath queries $this->ns_prefix = isset($namespaces['pre']) ? 'pre:' : ''; // your xpath queries look like this (section/pre:value or section/value) $res = $this->simple_xml->xpath('section/'. $this->ns_prefix .'value'); ?> It is not an elegant solution but it I couldn't find a better one. (Add a registerNamespace($prefix, $url) method? ;)) http://php.net/manual/en/function.simplexml-element-registerXPathNamespace.php

« previous php.notes (#160701) next »