Simple XMLElement Object
(
[IpStatus] => 1
[ti_pid_20642] => SimpleXmlElement Object
(
我有一个上面格式的SimpleXMLElment,这个XML是在运行时生成的,它的节点值如ti_pid_20642
部分是dnymaic,例如ti_pid_3232
,ti-pid_2323
, ti_pid_anyumber
。
我的问题是如何获取这些节点值及其使用PHP的孩子?
答案 0 :(得分:0)
要使用SimpleXML获取XML 字符串中使用的所有节点名称,您可以使用SimpleXMLIterator
:
$tagnames = array_keys(iterator_to_array(
new RecursiveIteratorIterator(
new SimpleXMLIterator($string)
, RecursiveIteratorIterator::SELF_FIRST
)
));
print_r($tagnames);
哪个可以给你示范(你没有在你的问题中提供任何XML,Demo):
Array
(
[0] => IpStatus
[1] => ti_pid_20642
[2] => dependend
[3] => ti-pid_2323
[4] => ti_pid_anyumber
[5] => more
)
如果您在提供包含有效XML的字符串时遇到问题,请使用现有的SimpleXMLelement和create an XML string out of it:
$string = $simpleXML->asXML();
但是,如果您想从SimpleXML对象获取所有标记名但又不想将其转换为字符串,则还可以为SimpleXMLElement
创建递归迭代器:
class SimpleXMLElementIterator extends IteratorIterator implements RecursiveIterator
{
private $element;
public function __construct(SimpleXMLElement $element) {
parent::__construct($element);
}
public function hasChildren() {
return (bool)$this->current()->children();
}
public function getChildren() {
return new self($this->current()->children());
}
}
它的用法类似(Demo):
$it = new RecursiveIteratorIterator(
new SimpleXMLElementIterator($xml), RecursiveIteratorIterator::SELF_FIRST
);
$tagnames = array_keys(iterator_to_array($it));
这取决于你需要什么。
使用命名空间元素变得不那么简单了。取决于您是仅要获取本地名称还是namspace名称,甚至是带有标记名的名称空间URI。
可以更改给定的SimpleXMLElementIterator
以支持跨命名空间的元素的迭代,默认情况下,simplexml仅提供对默认命名空间中元素的遍历:
/**
* SimpleXMLElementIterator over all child elements across namespaces
*/
class SimpleXMLElementIterator extends IteratorIterator implements RecursiveIterator
{
private $element;
public function __construct(SimpleXMLElement $element) {
parent::__construct(new ArrayIterator($element->xpath('./*')));
}
public function key() {
return $this->current()->getName();
}
public function hasChildren() {
return (bool)$this->current()->xpath('./*');
}
public function getChildren() {
return new self($this->current());
}
}
然后,您需要检查每个元素的命名空间 - 例如,使用命名空间的修改后的XML文档:
<root xmlns="namspace:default" xmlns:ns1="namespace.numbered.1">
<ns1:IpStatus>1</ns1:IpStatus>
<ti_pid_20642>
<dependend xmlns="namspace:depending">
<ti-pid_2323>ti-pid_2323</ti-pid_2323>
<ti_pid_anyumber>ti_pid_anyumber</ti_pid_anyumber>
<more xmlns:ns2="namspace.numbered.2">
<ti_pid_20642 ns2:attribute="test">ti_pid_20642</ti_pid_20642>
<ns2:ti_pid_20642>ti_pid_20642</ns2:ti_pid_20642>
</more>
</dependend>
</ti_pid_20642>
</root>
结合上面的更新SimpleXMLIterator
,以下示例代码演示了新行为:
$xml = new SimpleXMLElement($string);
$it = new RecursiveIteratorIterator(
new SimpleXMLElementIterator($xml), RecursiveIteratorIterator::SELF_FIRST
);
$count = 0;
foreach ($it as $name => $element) {
$nsList = $element->getNamespaces();
list($ns, $nsUri) = each($nsList);
printf("#%d: %' -20s %' -4s %s\n", ++$count, $name, $ns, $nsUri);
}
输出(Demo):
#1: IpStatus ns1 namespace.numbered.1
#2: ti_pid_20642 namspace:default
#3: dependend namspace:depending
#4: ti-pid_2323 namspace:depending
#5: ti_pid_anyumber namspace:depending
#6: more namspace:depending
#7: ti_pid_20642 namspace:depending
#8: ti_pid_20642 ns2 namspace.numbered.2
玩得开心。