php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #62260 XPath does not search correctly in nodes with text and other nodes
Submitted: 2012-06-08 07:34 UTC Modified: 2012-06-15 09:03 UTC
From: yajo dot sk8 at gmail dot com Assigned:
Status: Closed Package: *XML functions
PHP Version: 5.3.13 OS: Linux
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: yajo dot sk8 at gmail dot com
New email:
PHP Version: OS:

 

 [2012-06-08 07:34 UTC] yajo dot sk8 at gmail dot com
Description:
------------
When a node has inner nodes and you want to search into its text value, only the first text node is selected.

This is wrong because, as http://www.w3.org/TR/xpath/#path-abbrev says:
> text() selects all text node children of the context node

Test script:
---------------
$xml = <<<END
<?xml version="1.0" encoding="UTF-8"?>
<root>
    <first>
        Hello
        <second>
            world
        </second>
        world
    </first>
</root>
END;

$doc = DOMDocument::loadXML($xml);
$xpath = new DOMXPath($doc);

foreach ($xpath->query('//*[contains(text(), "world")]') as $node)
    echo $node->nodeName . PHP_EOL;

Expected result:
----------------
first
second

Actual result:
--------------
second

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2012-06-08 08:29 UTC] salathe@php.net
I may be wrong, but my understanding is as follows.

text() returns a list of node [1], whereas contains() expects two string arguments [2].  Because of this the list of 
text nodes is converted to a string, as with string():

"A node-set is converted to a string by returning the string-value of the node in the node-set that is first in 
document order. If the node-set is empty, an empty string is returned." [3]

[1] http://www.w3.org/TR/xpath/#path-abbrev
[2] http://www.w3.org/TR/xpath/#function-contains
[3] http://www.w3.org/TR/xpath/#function-string
 [2012-06-15 09:03 UTC] yajo dot sk8 at gmail dot com
-Status: Open +Status: Closed
 [2012-06-15 09:03 UTC] yajo dot sk8 at gmail dot com
Salathe, thanks for the point, you are right.

Replacing the xquery by '//text()[contains(., "world")]/..' works perfectly.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 18:01:29 2024 UTC