Bug #66359 [Com]: Corrupt implementation of Traversable in DOMNodeList, when created by DOMXPath
| From: | jpauli@php.net | Date: | Thu, 30 Jan 2014 16:35:50 +0000 |
| Subject: | Bug #66359 [Com]: Corrupt implementation of Traversable in DOMNodeList, when created by DOMXPath | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-184092@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=66359&edit=1
ID: 66359
Comment by: jpauli@php.net
Reported by: r dot wilczek at web-appz dot de
Summary: Corrupt implementation of Traversable in
DOMNodeList, when created by DOMXPath
Status: Open
Type: Bug
Package: DOM XML related
Operating System: Linux
PHP Version: 5.5.7
Block user comment: N
Private report: N
New Comment:
DomXpath and DomDocument don't set the node to the same type.
Iterator uses the type to dispatch a different iteration method
(http://lxr.php.net/xref/PHP_5_5/ext/dom/dom_iterators.c#203)
DomDocument iterator creation : http://lxr.php.net/xref/PHP_5_5/ext/dom/php_dom.c#1114
DomXpath iterator creation :
http://lxr.php.net/xref/PHP_5_5/ext/dom/xpath.c#dom_xpath_iter
Previous Comments:
------------------------------------------------------------------------
[2013-12-27 11:30:01] r dot wilczek at web-appz dot de
Description:
------------
A DOMNodeList created by evaluating a DOMXPath is not correctly traversable.
Equivalent instances of DOMNodeList created by getElementsByTagName() etc. do not have this problem.
The example below creates equivalent nodelists and shows the incorrect iteration of the one created
by evaluating an XPath-expression.
Test script:
---------------
function printList(\DOMNodeList $list)
{
foreach ($list as $outer) {
/* @var $outer \DOMNode */
echo 'outer: ' . $outer->nodeValue . PHP_EOL;
foreach ($list as $inner) {
/* @var $inner \DOMNode */
echo ' inner: ' . $inner->nodeValue . PHP_EOL;
}
}
}
/**
* @return DOMNodeList
*/
function getByXpath(\DOMDocument $dom)
{
return (new \DOMXPath($dom))->evaluate('item');
}
/**
* @return DOMNodeList
*/
function getByTagName(\DOMDocument $dom)
{
return $dom->getElementsByTagName('item');
}
$xml = <<< XML
<root>
<item>1</item>
<item>2</item>
<item>3</item>
</root>
XML;
$dom = new \DOMDocument;
$dom->loadXml($xml);
printList(getByTagName($dom));
echo '-------------' . PHP_EOL;
printList(getByXpath($dom));
Expected result:
----------------
outer: 1
inner: 1
inner: 2
inner: 3
outer: 2
inner: 1
inner: 2
inner: 3
outer: 3
inner: 1
inner: 2
inner: 3
-------------
outer: 1
inner: 1
inner: 2
inner: 3
outer: 2
inner: 1
inner: 2
inner: 3
outer: 3
inner: 1
inner: 2
inner: 3
Actual result:
--------------
outer: 1
inner: 1
inner: 2
inner: 3
outer: 2
inner: 1
inner: 2
inner: 3
outer: 3
inner: 1
inner: 2
inner: 3
-------------
outer: 1
inner: 1
inner: 2
inner: 3
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=66359&edit=1