Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:29654 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 52999 invoked by uid 1010); 22 May 2007 08:23:07 -0000 Delivered-To: ezmlm-scan-internals@lists.php.net Delivered-To: ezmlm-internals@lists.php.net Received: (qmail 52984 invoked from network); 22 May 2007 08:23:07 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 22 May 2007 08:23:07 -0000 Authentication-Results: pb1.pair.com smtp.mail=kenashkov@gmail.com; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=kenashkov@gmail.com; sender-id=pass; domainkeys=bad Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.132.245 as permitted sender) DomainKey-Status: bad X-DomainKeys: Ecelerity dk_validate implementing draft-delany-domainkeys-base-01 X-PHP-List-Original-Sender: kenashkov@gmail.com X-Host-Fingerprint: 209.85.132.245 an-out-0708.google.com Received: from [209.85.132.245] ([209.85.132.245:54137] helo=an-out-0708.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 9C/50-46001-968A2564 for ; Tue, 22 May 2007 04:23:06 -0400 Received: by an-out-0708.google.com with SMTP id d31so441791and for ; Tue, 22 May 2007 01:23:02 -0700 (PDT) DKIM-Signature: a=rsa-sha1; c=relaxed/relaxed; d=gmail.com; s=beta; h=domainkey-signature:received:received:message-id:date:from:to:subject:mime-version:content-type; b=H366/du4BYOyqDHVcFLDvVxkeRSxHWkMcJsnqVtSMqcQdrJcMC9Yy9alGMwpJ1JWxmcN5N0QXht0LCT/KLpEjLZUiQ/1/0Fq0yYr0Tzv6vswe3g5Lo+hHIIe47UCmd2YpilHMcsni2et/FNNSPM0JpZbBg40MJOYGR2nKMmKq3U= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=beta; h=received:message-id:date:from:to:subject:mime-version:content-type; b=hLQA1qggPHCXAQByvrSRf3NDySzFzjvUw+lfk98KpwuySArM8PIAZDgDi3fvyU8mZSlqKOtydXfqamt0485S+NuLVqSV42+zPGczEuZSTYAyhivs1C3p2AYVh+si+xsqPFj9zMqDRzj15GSFW6RjihmbDxQKHOtgDWJEJbC26Sg= Received: by 10.100.126.2 with SMTP id y2mr3613316anc.1179822182742; Tue, 22 May 2007 01:23:02 -0700 (PDT) Received: by 10.100.166.5 with HTTP; Tue, 22 May 2007 01:23:02 -0700 (PDT) Message-ID: <261daaa10705220123m41b254a6p6b44d21b29ad1d4c@mail.gmail.com> Date: Tue, 22 May 2007 11:23:02 +0300 To: internals@lists.php.net, "Vesselin Kenashkov" MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="----=_Part_148518_11689940.1179822182696" Subject: unexpected behaviour in SimpleXML (php 5.2.2) From: kenashkov@gmail.com ("Vesselin Kenashkov") ------=_Part_148518_11689940.1179822182696 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit Content-Disposition: inline Hello everybody, Before writing to the dev-list I posted a message in the Zend dev forum (in fact it was an year ago about the same issues), as well on PHP general list, but without any reply or comment. I think two things in the SimpleXML are inconsistent, or at least unexpected from the php developer. Here is the first one - how one can find does a SimpleXMLElement has child nodes? Here is an example: -------- $str = ''; $x = new SimpleXMLElement($str); if($x->subnode->children()) print 'yes'; else print 'no'; --------- will print 'no'; If the $str=''; it will print yes. But the same will happen if the subnode has an attribute like: $str = ''; But if we use foreach($x->subnode->children() as $key=>$value) in the latter example we will not get anything (which is correct). I think is wrong the children() method to return object when there are no child objects and the node has attributes. The workaround I use is to extend the SimpleXMLElement -------- class SimpleXMLElement2 extends SimpleXMLElement { public function has_children() { foreach($this->children() as $node) return true; return false; } } ------ And then we can check with if($x->subnode->has_children()) Issue #2: Xpath on nodes. Let we have the example: ----------------- $str = ''; $x = new SimpleXMLElement($str); $r1 = $x->xpath('/*'); print $r1[0]->getName();//prints rootnode $r2 = $x->level1_node1[0]->xpath('/*'); print $r2[0]->getName();//prints rootnode $z = clone $x->level1_node1[0]; $r3 = $z->xpath('/*'); print $r3[0]->getName();//prints rootnode //print $z->getName();//ok ------------------ I personally think that the xpath must be evaluated against the node which method is called, not always against the rootnode. So in the second example I would expect it to return level1_node1, and especially in the thirds example. Even in the third example the xpath is evaluated against the original XML structure, not the subnode (level1_node1). I think this is incorrect and leads to a confusion - for example we can pass a node to a function like: -------- function do_something($node) { //print $node->getName();//prints correct - the name of the supplied node - level1_node1 $r1 = $node->xpath('/*'); print $r1[0]->getName(); } do_something(clone $x->level1_node1[0]); -------- The do_something function is not aware at all about the full xml structure and one could think that the expression will be evaluated just against the supplied node, but it is not that the case. Please give your comments - do you find this functionality OK, is it a bug, or I miss something. Vesselin Kenashkov ------=_Part_148518_11689940.1179822182696--