inconsistency in SimpleXML

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello everybody,

An year ago I was playing with the SimpleXML in php and found some issues
and abandoned php5 for a year. Now I'm back to it and I found that the
issius are still there.

Here is the first one - how one can find does a SimpleXMLElement has child
nodes?
Here is an example:
--------
$str = '<rootnode><subnode></subnode></rootnode>';
$x = new SimpleXMLElement($str);

if($x->subnode->children())
   print 'yes';
   else
       print 'no';
---------
will print 'no';

If the
$str='<rootnode><subnode><newnode></newnode></subnode></rootnode>';
it will print yes.
But the same will happen if the subnode has an attribute like:
$str = '<rootnode><subnode id="2"></subnode></rootnode>';

But if we use foreach($x->subnode->children() as $key=>$value)
in the latter example we will not get anything.
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 =
'<rootnode><level1_node1><level2_node1></level2_node1></level1_node1><level1_node2></level1_node2></rootnode>';
$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.
And I do not have a workaround for that for the moment.
Any comments, solutions, and opinions about that SimpleXML functionality are
welcome.

Vesselin Kenashkov

[Index of Archives]     [PHP Home]     [Apache Users]     [PHP on Windows]     [Kernel Newbies]     [PHP Install]     [PHP Classes]     [Pear]     [Postgresql]     [Postgresql PHP]     [PHP on Windows]     [PHP Database Programming]     [PHP SOAP]

  Powered by Linux