Php 如何区分表示元素和属性的SimpleXML对象?
我需要以特定的方式打印任意SimpleXML对象,并对属性节点进行特殊处理 问题在于SimpleXML元素和属性似乎使用完全相同的类,属性节点甚至假装支持Php 如何区分表示元素和属性的SimpleXML对象?,php,reflection,simplexml,Php,Reflection,Simplexml,我需要以特定的方式打印任意SimpleXML对象,并对属性节点进行特殊处理 问题在于SimpleXML元素和属性似乎使用完全相同的类,属性节点甚至假装支持attributes()方法,而SimpleXML隐藏了其内部,因此似乎没有任何方法来判断节点的类型(除了生成XML和重新分析它) 两者给出相同的结果: $element=新的SimpleXMLElement('test'); echo$元素; 打印(元素); $element=新的SimpleXMLElement(“”); echo$elem
attributes()
方法,而SimpleXML隐藏了其内部,因此似乎没有任何方法来判断节点的类型(除了生成XML和重新分析它)
两者给出相同的结果:
$element=新的SimpleXMLElement('test');
echo$元素;
打印(元素);
$element=新的SimpleXMLElement(“”);
echo$element['attr'];
打印($element['attr']);
是否存在允许标识SimpleXML中节点类型的隐藏属性/方法?等同于DOM的$node->nodeType
或$node instanceof DOMAttr
?(我不能改用DOM,对SimpleXML的支持是核心要求)。您需要:
函数xml\u out($el){
$name=$el->getName();
回声“”(字符串)$el;
如果(计数($el->children()){
foreach($el->children()作为$c){
xml_out($c);
}
}
回声';
}
可能需要一些调整。不幸的是,没有隐藏的属性或方法允许识别SimpleXML中的节点类型。SimpleXML只使用一个类,元素没有任何指向其父类的内容。如果您尝试下面的反射,您将看到没有什么可以区分元素或属性
$element = new SimpleXMLElement('<foo>test</foo>');
echo ReflectionObject::export($element);
$element = new SimpleXMLElement('<foo attr="test">test</foo>');
echo ReflectionObject::export($element['attr']);
$element=新的SimpleXMLElement('test');
回波反射对象::导出($element);
$element=新的SimpleXMLElement(“测试”);
回波反射对象::导出($element['attr']);
但是,如果元素具有属性,则可以检测该属性。因此,您必须假设传入的所有元素都具有属性。有了这个假设,你就可以把它们区分开来
$element = new SimpleXMLElement('<foo attr="test">test</foo>');
echo ReflectionObject::export($element);
echo ReflectionObject::export($element['attr']);
$element=新的SimpleXMLElement('test');
回波反射对象::导出($element);
回波反射对象::导出($element['attr']);
这是我能想到的最好的了。请记住,没有属性的元素可能仍然返回false
function isNotAttribute($simpleXML)
{
return (count($simpleXML->attributes()) > 0);
}
$element = new SimpleXMLElement('<foo attr="test">test</foo>');
var_dump(isNotAttribute($element));
var_dump(isNotAttribute($element['attr']));
// returns
bool(true)
bool(false)
函数不是属性($simpleXML)
{
返回(计数($simpleXML->attributes())>0);
}
$element=新的SimpleXMLElement(“测试”);
var_dump(isNotAttribute($element));
变量转储(isNotAttribute($element['attr']);
//返回
布尔(真)
布尔(假)
是的,有办法。好的,您可以通过API检索到任何优雅的东西,但是SimpleXML的内部某处正在跟踪它是什么,并且它会产生差异,例如,当您调用诸如getName()或asXML()之类的函数时
$element=新的SimpleXMLElement('test');
打印($element->getName());
打印($element->asXML());
回显“--------------\n”;
$element=新的SimpleXMLElement(“”);
$at=$element['attr'];
打印($at->getName());
打印($at->asXML());
福
测试
------------------
属性
attr=“测试”
你的代码不会赢得选美比赛,但至少你可以做到。用palako指出的方法,这样的函数可能会起作用:
function is_attribute($node) {
return !($node->asXML()[0] == "<")
}
函数是_属性($node){
return!($node->asXML()[0]=”
是否有一个隐藏属性/方法允许识别SimpleXML中的节点类型?相当于DOM的$node->nodeType或$node instanceof DOMAttr?(我不能改用DOM,对SimpleXML的支持是核心要求)
答案是否定的……而且是肯定的。SimpleXML没有这样的属性,但有一个好消息:SimpleXML和DOM是同一个硬币的两面。(硬币是libxml;)您不必选择一个或另一个,两个都可以使用!您可以将simplexmlement
转换为DOMNode
,反之亦然。在您的情况下,您可以执行以下操作:
$element = new SimpleXMLElement('<foo attr="test" />');
$is_attr = (dom_import_simplexml($element['attr'])->nodeType === XML_ATTRIBUTE_NODE);
$element=新的SimpleXMLElement(“”);
$is_attr=(dom_import_simplexml($element['attr'])->nodeType==XML\u ATTRIBUTE\u NODE);
如果这是您经常做的事情,或者您不想处理DOM/SimpleXML杂耍,那么您可以看看
$element=newsimpledom(“”);
$is_attr=($element['attr']->nodeType()==XML_ATTRIBUTE_NODE);
SimpleXMLElement
中没有允许您区分这些属性的内置属性
但是,正如其他人所建议的那样,该函数有时可以动态更改节点,例如,如果您传入一个ChildNode或命名的ChildNode列表,它将获取这些节点并将它们转换为第一个元素
如果它是一个空列表,例如,没有从attributes()
返回的属性或不存在的命名子节点,它将发出警告,告诉您提供了无效的节点类型:
警告:dom\u import\u simplexml():要导入的节点类型无效
因此,如果您需要一个简洁的布尔值true
/false
,下面是它如何与Simplexml一起工作的:
$isElement = $element->xpath('.') == array($element);
$isAttribute = $element[0] == $element
and $element->xpath('.') != array($element);
它的工作原理与属性列表和元素列表类似,我已经,你需要有一些具体的知识来评估什么,所以我为它创建了一个备忘表:
+------------------+---------------------------------------------+
| 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) |
+------------------+---------------------------------------------+
$element = new SimpleXMLElement('<foo attr="test" />');
$is_attr = (dom_import_simplexml($element['attr'])->nodeType === XML_ATTRIBUTE_NODE);
$element = new SimpleDOM('<foo attr="test" />');
$is_attr = ($element['attr']->nodeType() === XML_ATTRIBUTE_NODE);
$isElement = $element->xpath('.') == array($element);
$isAttribute = $element[0] == $element
and $element->xpath('.') != array($element);
+------------------+---------------------------------------------+
| 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) |
+------------------+---------------------------------------------+