php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #41663 Xpath evaluation in SimpleXMLElement
Submitted: 2007-06-12 08:10 UTC Modified: 2007-06-12 13:18 UTC
From: kenashkov at gmail dot com Assigned:
Status: Not a bug Package: SimpleXML related
PHP Version: 5.2.3 OS: Fedora Core 4
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: kenashkov at gmail dot com
New email:
PHP Version: OS:

 

 [2007-06-12 08:10 UTC] kenashkov at gmail dot com
Description:
------------
The evaluation of the Xpath expressions is not relative to the node against which they are called ([2]). Worse - even after cloning a node from the structure and evaluating the xpath, the xpath expression seems to be evaluated against the original structure, not against the new one (which is a copy of a part of the original) ([3]).

This was discussed in the dev-list here:
http://marc.info/?l=php-dev&m=118001203709813&w=2

If this is not a bug, but expected result, I think a note addressing this behaviour must be added in the docs.

Reproduce code:
---------------
$str = '<rootnode><level1_node1><level2_node1></level2_node1></level1_node1><level1_node2></level1_node2></rootnode>';
$x = new SimpleXMLElement($str);

//[1]
$r1 = $x->xpath('/*');
print $r1[0]->getName().' ';

//[2]
$r2 = $x->level1_node1[0]->xpath('/*');
print $r2[0]->getName().' ';

//[3]
$z = clone $x->level1_node1[0];
$r3 = $z->xpath('/*');
print $r3[0]->getName().' ';



Expected result:
----------------
rootnode level1_node1 level1_node1

Actual result:
--------------
rootnode rootnode rootnode

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2007-06-12 12:44 UTC] rrichards@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php

The results are exactly what you requested based on your XPath expression. You used absolute paths not relative:
http://www.w3.org/TR/xpath#location-paths
 [2007-06-12 12:50 UTC] kenashkov at gmail dot com
Yes - I use absolute expression. But at least in the last example [3]:
$z = clone $x->level1_node1[0];
$r3 = $z->xpath('/*');
print $r3[0]->getName().' ';

I use the $z object - not the x. And the $z object does not has any node called rootnode. The expression is again evaluated against the $x structure, not the $z.
This could be a problem in the case:

$z = clone $x->level1_node1[0];
function do_something($z)
{
$z->xpath('/*');//some absolute expression
}

Where the function do_something is totally unaware of the existance of the $x var. If this is still expected then how one can evaluate an absolute xpath expression inside the do_something function, as it will always do it for the $x structure, not the locally available $z structure.
I think at least this must be documented and a workaround must be provide in the docs.
 [2007-06-12 13:08 UTC] rrichards@php.net
Still incorrect:
The cloned node is still part of the document (just not linked in).
Using / causes expression to be evaluated against the document.
/* will select the top level element in the same document as the context node

Use ./ to evaluate against and in scope of context node

Note: There was a bug in earlier versions of SimpleXML (pre 5.2 I believe) where the relative path didn't work correctly against the context.
 [2007-06-12 13:18 UTC] kenashkov at gmail dot com
Yes, I experienced strange behaviour with the relative path (exactly in a function - like the example I gave) and this is why I gave now the example with absolute path.
I just expected clone to get the node out of the structure.
Case closed.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Oct 27 16:01:27 2024 UTC