Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 12 of 12

Thread: PHP bug?

  1. #1
    Regular Coder
    Join Date
    Jun 2010
    Posts
    293
    Thanks
    63
    Thanked 8 Times in 8 Posts

    PHP bug?

    Consider the following very simple piece of code:

    PHP Code:
    $doc = new DOMDocument();
    $doc->loadXML("<?xml version='1.0' ?><xml/>");

    $xpath = new DOMXpath($doc);

    $xml = $xpath->query("/xml")->item(0);
    var_dump($xpath->query(".//xml", $xml)->length);
    The output from this is int(1), right?

    Wrong! It's int(0).

    I.e. DOMXPath::query won't return the context node itself as part of the result. So for example, you would get int(1) for <xml><xml/></xml> in my above code, rather than int(2) ... I think it should be int(2) in that case, otherwise there's no way of selecting the context node itself using XPath. I guess it all depends on how ".//{name}" is supposed to be interpreted.

    PHP bug, I think ... am I right?
    Last edited by XmisterIS; 02-09-2012 at 11:11 PM.

  • #2
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,987
    Thanks
    4
    Thanked 2,660 Times in 2,629 Posts
    Tag XML doesn't contain any child nodes XML, so the count of an .//XML on the XML element will yield no results. So an output of 0 for your count is correct.

  • #3
    Regular Coder
    Join Date
    Jun 2010
    Posts
    293
    Thanks
    63
    Thanked 8 Times in 8 Posts
    Hmmm ... it still outputs int(0) for the query $xpath->evaluate("xml", $xml); though ... surely that's wrong?

  • #4
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,987
    Thanks
    4
    Thanked 2,660 Times in 2,629 Posts
    No, that's the same thing. You are still working from $xml which has no children.

  • #5
    Super Moderator
    Join Date
    Feb 2009
    Location
    England
    Posts
    539
    Thanks
    8
    Thanked 63 Times in 54 Posts
    Yeah, I tried it with <?xml version='1.0' ?><xml><a /></xml> and it still says 0.

    I've never used DOMXpath and hoped my Komodo IDE and xdebug would help out, but the resources DOMXpath returns are apparently not inspectable.
    lamped.co.uk :: Design, Development & Hosting
    marcgray.co.uk :: Technical blog

  • #6
    Regular Coder
    Join Date
    Jun 2010
    Posts
    293
    Thanks
    63
    Thanked 8 Times in 8 Posts
    Quote Originally Posted by Fou-Lu View Post
    No, that's the same thing. You are still working from $xml which has no children.
    but, but, but ... I thought the queries "xml" and ".//xml" would look for all elements among the context node and it's children, not just among the context node's children? I am wrong in thinking that?

    EDIT: Lamped - the return value of DOMXPath::query is a DOMNodeList, which you can iterate over in a loop.
    Last edited by XmisterIS; 02-09-2012 at 11:30 PM.

  • #7
    Super Moderator Inigoesdr's Avatar
    Join Date
    Mar 2007
    Location
    Florida, USA
    Posts
    3,642
    Thanks
    2
    Thanked 405 Times in 397 Posts
    Quote Originally Posted by Lamped View Post
    Yeah, I tried it with <?xml version='1.0' ?><xml><a /></xml> and it still says 0.
    It would be:
    PHP Code:
    <?php

    $doc 
    = new DOMDocument();
    $doc->loadXML("<?xml version='1.0' ?><xml><a /></xml>");

    $xpath = new DOMXpath($doc);

    $xml $xpath->query("/xml")->item(0);
    var_dump($xpath->query(".//a"$xml)->length); // int(1)

  • #8
    Regular Coder
    Join Date
    Jun 2010
    Posts
    293
    Thanks
    63
    Thanked 8 Times in 8 Posts
    Quote Originally Posted by Inigoesdr View Post
    It would be:
    PHP Code:
    <?php

    $doc 
    = new DOMDocument();
    $doc->loadXML("<?xml version='1.0' ?><xml><a /></xml>");

    $xpath = new DOMXpath($doc);

    $xml $xpath->query("/xml")->item(0);
    var_dump($xpath->query(".//a"$xml)->length); // int(1)
    So it would ... and var_dump($xpath->query("/xml", $xml)->length); yeilds int(1) ... I was getting confused with my xpath there ... Lol!

  • #9
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,987
    Thanks
    4
    Thanked 2,660 Times in 2,629 Posts
    Correct, it will flow from parent through child within that context. That thinking is correct.
    But your perception of the context is wrong. The highest you can go is documentElement, which is the root. <XML> is your root so it can only find children below this level:
    PHP Code:
    <?php
    $doc 
    = new DOMDocument();
    $doc->loadXML("<?xml version='1.0' ?><xml><xml /><xml /></xml>");

    $xpath = new DOMXpath($doc);

    $xmlQ $xpath->query(".//xml");
    printf('Total for .//xml: %d' PHP_EOL$xmlQ->length);

    $doc->loadXML("<?xml version='1.0' ?><root><xml><xml /><xml /></xml></root>");

    $xpath = new DOMXpath($doc);

    $xmlQ $xpath->query(".//xml");
    printf('Total for .//xml: %d' PHP_EOL$xmlQ->length);
    This will produce the results:
    Code:
    Total for .//xml: 2
    Total for .//xml: 3
    The first XML contains three nodes, the root under XML and two children to root under XML. So the count of .//xml on documentElement produces two results.
    The second contains the same as above, but wrapped in <root>. Root is now the documentElement, so the context can now count all children of documentRoot which is one XML with two nested XML tags. That count is therefore 3.

  • #10
    Super Moderator
    Join Date
    Feb 2009
    Location
    England
    Posts
    539
    Thanks
    8
    Thanked 63 Times in 54 Posts
    EDIT: Lamped - the return value of DOMXPath::query is a DOMNodeList, which you can iterate over in a loop.
    You know, I've spent too long relying on xdebug, that a non-inspectable resource like DOMNodeList tends to throw me.

    Being stubborn as I am, rather than correct myself, I think I'll contact Derek Rethans and ActiveState to see if I can get an automated solution to this sort of thing.
    lamped.co.uk :: Design, Development & Hosting
    marcgray.co.uk :: Technical blog

  • #11
    Regular Coder
    Join Date
    Jun 2010
    Posts
    293
    Thanks
    63
    Thanked 8 Times in 8 Posts
    Yes, I understand now. I've never before tried to extract the context node itself with a query, so it never occurred to me that my thinking was wrong!! Thanks.

  • #12
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,987
    Thanks
    4
    Thanked 2,660 Times in 2,629 Posts
    Quote Originally Posted by XmisterIS View Post
    Yes, I understand now. I've never before tried to extract the context node itself with a query, so it never occurred to me that my thinking was wrong!! Thanks.
    The thinking isn't wrong, its just where you think you are that's wrong. Easiest way I can think of this is to completely ignore the documentElement if you are working relative, and forget that its there. Absolute is fine, seeking //xml for example will find all three in that first block, but using .//xml will only find the two children (since the first XML is the parent of the document).


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •