Go Back   CodingForums.com > :: Server side development > PHP

Before you post, read our: Rules & Posting Guidelines

Reply
 
Thread Tools Rate Thread
Enjoy an ad free experience by logging in. Not a member yet? Register.
Old 02-09-2012, 10:51 PM   PM User | #1
XmisterIS
Regular Coder

 
Join Date: Jun 2010
Posts: 239
Thanks: 50
Thanked 6 Times in 6 Posts
XmisterIS is an unknown quantity at this point
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..
XmisterIS is offline   Reply With Quote
Old 02-09-2012, 11:08 PM   PM User | #2
Fou-Lu
God Emperor


 
Fou-Lu's Avatar
 
Join Date: Sep 2002
Location: Saskatoon, Saskatchewan
Posts: 15,650
Thanks: 4
Thanked 2,450 Times in 2,419 Posts
Fou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to all
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.
Fou-Lu is offline   Reply With Quote
Old 02-09-2012, 11:13 PM   PM User | #3
XmisterIS
Regular Coder

 
Join Date: Jun 2010
Posts: 239
Thanks: 50
Thanked 6 Times in 6 Posts
XmisterIS is an unknown quantity at this point
Hmmm ... it still outputs int(0) for the query $xpath->evaluate("xml", $xml); though ... surely that's wrong?
XmisterIS is offline   Reply With Quote
Old 02-09-2012, 11:17 PM   PM User | #4
Fou-Lu
God Emperor


 
Fou-Lu's Avatar
 
Join Date: Sep 2002
Location: Saskatoon, Saskatchewan
Posts: 15,650
Thanks: 4
Thanked 2,450 Times in 2,419 Posts
Fou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to all
No, that's the same thing. You are still working from $xml which has no children.
Fou-Lu is offline   Reply With Quote
Old 02-09-2012, 11:18 PM   PM User | #5
Lamped
Super Moderator


 
Join Date: Feb 2009
Location: England
Posts: 539
Thanks: 8
Thanked 63 Times in 54 Posts
Lamped will become famous soon enough
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
Lamped is offline   Reply With Quote
Old 02-09-2012, 11:26 PM   PM User | #6
XmisterIS
Regular Coder

 
Join Date: Jun 2010
Posts: 239
Thanks: 50
Thanked 6 Times in 6 Posts
XmisterIS is an unknown quantity at this point
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..
XmisterIS is offline   Reply With Quote
Old 02-09-2012, 11:29 PM   PM User | #7
Inigoesdr
Super Moderator


 
Inigoesdr's Avatar
 
Join Date: Mar 2007
Location: Florida, USA
Posts: 3,601
Thanks: 2
Thanked 397 Times in 390 Posts
Inigoesdr is a jewel in the roughInigoesdr is a jewel in the roughInigoesdr is a jewel in the rough
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)
Inigoesdr is offline   Reply With Quote
Old 02-09-2012, 11:33 PM   PM User | #8
XmisterIS
Regular Coder

 
Join Date: Jun 2010
Posts: 239
Thanks: 50
Thanked 6 Times in 6 Posts
XmisterIS is an unknown quantity at this point
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!
XmisterIS is offline   Reply With Quote
Old 02-09-2012, 11:36 PM   PM User | #9
Fou-Lu
God Emperor


 
Fou-Lu's Avatar
 
Join Date: Sep 2002
Location: Saskatoon, Saskatchewan
Posts: 15,650
Thanks: 4
Thanked 2,450 Times in 2,419 Posts
Fou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to all
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.
Fou-Lu is offline   Reply With Quote
Old 02-09-2012, 11:40 PM   PM User | #10
Lamped
Super Moderator


 
Join Date: Feb 2009
Location: England
Posts: 539
Thanks: 8
Thanked 63 Times in 54 Posts
Lamped will become famous soon enough
Quote:
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
Lamped is offline   Reply With Quote
Old 02-09-2012, 11:43 PM   PM User | #11
XmisterIS
Regular Coder

 
Join Date: Jun 2010
Posts: 239
Thanks: 50
Thanked 6 Times in 6 Posts
XmisterIS is an unknown quantity at this point
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.
XmisterIS is offline   Reply With Quote
Old 02-09-2012, 11:53 PM   PM User | #12
Fou-Lu
God Emperor


 
Fou-Lu's Avatar
 
Join Date: Sep 2002
Location: Saskatoon, Saskatchewan
Posts: 15,650
Thanks: 4
Thanked 2,450 Times in 2,419 Posts
Fou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to all
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).
Fou-Lu is offline   Reply With Quote
Reply

Bookmarks

Jump To Top of Thread


Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 10:59 PM.


Advertisement
Log in to turn off these ads.