|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2009-09-07 08:41 UTC] olav dot morken at uninett dot no
Description:
------------
When processing an XML document with namespaces, an XPath query for a node with a different namespace but the same namespace prefix fails.
This appears to be a conflict between the XPath namespaces and the document namespaces. It works if either:
- The prefix in the query is replaced with a prefix that doesn't
exist in the document.
- If the prefix in the query matches the prefix in the document.
This was tested with:
- PHP 5.3 from debian experimental: 5.3.0-3
- libxml2 2.7.3.dfsg-2.1
Reproduce code:
---------------
$doc = new DOMDocument();
$doc->loadXML('<prefix:root xmlns:prefix="urn:a" />');
$xp = new DOMXPath($doc);
$xp->registerNamespace('prefix', 'urn:b');
echo($xp->query('//prefix:root')->length . "\n");
Expected result:
----------------
It should not find the root node, since we ask for a node in a different prefix. I.e. it should print '0'.
Actual result:
--------------
It finds the root node, i.e. it prints '1'.
Patchesbug49490 (last revision 2010-05-02 16:00 UTC by david dot zuelke at bitextender dot com)Pull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Fri Oct 24 00:00:02 2025 UTC |
It looks like DOMXPath->evaluate()/DOMXPath->query() registers the namespace prefixes of the given context and overrides any definition from DOMXPath->registerNamespace(). PHP should not register any namespaces from the context or at least prefer manual registrations over automatic. Reproduce code: --------------- $dom = new DOMDocument(); $dom->loadXML( '<foobar><a:foo xmlns:a="urn:a">'. '<b:bar xmlns:b="urn:b"/></a:foo>'. '</foobar>' ); $xpath = new DOMXPath($dom); //get context node and check "a:foo" $context = $dom->documentElement->firstChild; var_dump($context->tagName); // try to override the context node $xpath->registerNamespace('a', 'urn:b'); var_dump( $xpath->evaluate( 'descendant-or-self::a:*', $context )->item(0)->tagName ); // use a prefix not used in context $xpath->registerNamespace('prefix', 'urn:b'); var_dump( $xpath->evaluate( 'descendant-or-self::prefix:*', $context )->item(0)->tagName ); Expected result: ---------------- string(5) "a:foo" string(5) "b:bar" string(5) "b:bar" Actual result: ---------------- string(5) "a:foo" string(5) "a:foo" string(5) "b:bar"