I need to print arbitrary SimpleXML objects in a specific manner, with special handling of attribute nodes.
The problem is that SimpleXML elements and attributes seem to use exactly the same class, attribute node even pretends to support attributes()
method, and SimpleXML hides its internals, so there doesn't seem to be any way to tell type of node (short of generating XML and reparsing it).
Both give identical result:
$element = new SimpleXMLElement('<foo>test</foo>');
echo $element;
print_r($element);
$element = new SimpleXMLElement('<foo attr="test" />');
echo $element['attr'];
print_r($element['attr']);
Is there a hidden property/method that allows identifying type of node in SimpleXML? Equivalent of DOM's $node->nodeType
or $node instanceof DOMAttr
? (I can't use DOM instead, support for SimpleXML is core requirement).
There are no built-in properties in SimpleXMLElement
which would allow you to tell these apart.
As others have suggested dom_import_simplexml
can be appropriate, however, that function can change nodes on the fly sometimes, for example, if you pass in a list of childnodes or named childnodes, it will take those and turn them into the first element.
If it's an empty list, for example no attributes returned from attributes()
or non-existing named childnodes, it will give a warning telling you an invalid nodetype has been given:
Warning: dom_import_simplexml(): Invalid Nodetype to import
So if you need this precise with a snappy boolean true
/false
, here is how it works with Simplexml:
$isElement = $element->xpath('.') == array($element);
$isAttribute = $element[0] == $element
and $element->xpath('.') != array($element);
It works similar with attribute lists and element lists, I've just blogged about this in the morning, you need to have some specific knowledge about what to evaluate for what, so I created a cheatsheet for it:
+------------------+---------------------------------------------+
| TYPE | TEST |
+------------------+---------------------------------------------+
| Element | $element->xpath('.') == array($element) |
+------------------+---------------------------------------------+
| Attribute | $element[0] == $element |
| | and $element->xpath('.') != array($element) |
+------------------+---------------------------------------------+
| Attributes | $element->attributes() === NULL |
+------------------+---------------------------------------------+
| Elements | $element[0] != $element |
| | and $element->attributes() !== NULL |
+------------------+---------------------------------------------+
| Single | $element[0] == $element |
+------------------+---------------------------------------------+
| Empty List | $element[0] == NULL |
+------------------+---------------------------------------------+
| Document Element | $element->xpath('/*') == array($element) |
+------------------+---------------------------------------------+
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With