How to tell apart SimpleXML objects representing element and attribute?
php, reflection, simplexml
Solution
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) |
+------------------+---------------------------------------------+
- SimpleXML Type Cheatsheet (12 Feb 2013; by hakre)
Problem
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).