有没有办法通过节点名称获取简单的 XML 子元素?
Is there a way to get simple XML child elements by node name?
在 PHP 中,是否存在通过节点名称(递归)获取一个或多个子元素的现有方法,或者您是否必须自己为此编写一个函数?
例如,这是我的 XML:
<parent>
<child>
<grandchild>Jan</grandchild>
<grandchild>Kees</grandchild>
</child>
</parent>
我正在寻找一种 returns 类似的方法:
大批(
[0] => 'Jan',
[1] => 'Kees'
)
通过调用类似的东西:
$grandchildren = $xml->children('grandchild');
根据文档确实存在上述内容,但仅适用于命名空间。
e:下面接受的答案有效。这是我运行测试出来的
$xml = '
<parent>
<child>
<grandchild>Jan</grandchild>
<grandchild>Kees</grandchild>
</child>
</parent>';
$L_o_xml = new SimpleXMLElement($xml);
$L_o_child = $L_o_xml->xpath('//grandchild');
foreach( $L_o_child as $hi ){
print "\n".(string)$hi;
}
简单打印:
Jan
Kees
您可以通过多种复杂的方式使用 $xml->xpath()
到 select 节点:
$xml->xpath('//grandchild'); // select all grandchild elements in the document
JLRishe 已经给出了使用 xpath 查询的最方便的答案。
不过他没有解释原因。当您使用
$grandchildren = $xml->children('grandchild');
$xml
中元素的所有children名为“grandchild
”。但是该元素没有任何具有该名称的 child-elements 。它只有一个名为“child
”的 child 元素。这就是它不起作用的原因。
相反,您还想更深入地遍历 grand-children 和 grand-grand-children。 Xpath 在这里非常有用。然而,还有一个更专业的 SimpleXMLElement 名为 SimpleXMLIterator 允许递归遍历相当容易:
$xml = new SimpleXMLIterator($buffer);
$recursive = new RecursiveIteratorIterator($xml);
foreach ($recursive as $tag => $object) {
if ($tag !== 'grandchild') {
continue;
}
echo $object, "\n";
}
输出:
Jan
Kees
这个迭代器有点方便,但是,这里还有一种更直接的方法,没有任何新功能,它在所有 children 中查找,直到找到名为“grandchild
”的元素:
$stack = [new SimpleXMLElement($buffer)];
while ($has = array_pop($stack)) {
foreach ($has as $tag => $object) {
if ($tag !== 'grandchild') {
$stack[] = $object;
continue;
}
echo $object, "\n";
}
}
输出相同。
希望这两个例子能说明/解释一下为什么 children()
不足以完成您想要使用它的工作,因为它 return children of child仁.
完整示例:
<?php
/**
*
*/
$buffer = <<<'XML'
<parent>
<child>
<grandchild>Jan</grandchild>
<grandchild>Kees</grandchild>
</child>
</parent>
XML;
$xml = new SimpleXMLIterator($buffer);
$recursive = new RecursiveIteratorIterator($xml);
foreach ($recursive as $tag => $object) {
if ($tag !== 'grandchild') {
continue;
}
echo $object, "\n";
}
$stack = [new SimpleXMLElement($buffer)];
while ($has = array_pop($stack)) {
foreach ($has as $tag => $object) {
if ($tag !== 'grandchild') {
$stack[] = $object;
continue;
}
echo $object, "\n";
}
}
在 PHP 中,是否存在通过节点名称(递归)获取一个或多个子元素的现有方法,或者您是否必须自己为此编写一个函数?
例如,这是我的 XML:
<parent>
<child>
<grandchild>Jan</grandchild>
<grandchild>Kees</grandchild>
</child>
</parent>
我正在寻找一种 returns 类似的方法: 大批( [0] => 'Jan', [1] => 'Kees' )
通过调用类似的东西:
$grandchildren = $xml->children('grandchild');
根据文档确实存在上述内容,但仅适用于命名空间。
e:下面接受的答案有效。这是我运行测试出来的
$xml = '
<parent>
<child>
<grandchild>Jan</grandchild>
<grandchild>Kees</grandchild>
</child>
</parent>';
$L_o_xml = new SimpleXMLElement($xml);
$L_o_child = $L_o_xml->xpath('//grandchild');
foreach( $L_o_child as $hi ){
print "\n".(string)$hi;
}
简单打印:
Jan
Kees
您可以通过多种复杂的方式使用 $xml->xpath()
到 select 节点:
$xml->xpath('//grandchild'); // select all grandchild elements in the document
JLRishe 已经给出了使用 xpath 查询的最方便的答案。
不过他没有解释原因。当您使用
$grandchildren = $xml->children('grandchild');
$xml
中元素的所有children名为“grandchild
”。但是该元素没有任何具有该名称的 child-elements 。它只有一个名为“child
”的 child 元素。这就是它不起作用的原因。
相反,您还想更深入地遍历 grand-children 和 grand-grand-children。 Xpath 在这里非常有用。然而,还有一个更专业的 SimpleXMLElement 名为 SimpleXMLIterator 允许递归遍历相当容易:
$xml = new SimpleXMLIterator($buffer);
$recursive = new RecursiveIteratorIterator($xml);
foreach ($recursive as $tag => $object) {
if ($tag !== 'grandchild') {
continue;
}
echo $object, "\n";
}
输出:
Jan
Kees
这个迭代器有点方便,但是,这里还有一种更直接的方法,没有任何新功能,它在所有 children 中查找,直到找到名为“grandchild
”的元素:
$stack = [new SimpleXMLElement($buffer)];
while ($has = array_pop($stack)) {
foreach ($has as $tag => $object) {
if ($tag !== 'grandchild') {
$stack[] = $object;
continue;
}
echo $object, "\n";
}
}
输出相同。
希望这两个例子能说明/解释一下为什么 children()
不足以完成您想要使用它的工作,因为它 return children of child仁.
完整示例:
<?php
/**
*
*/
$buffer = <<<'XML'
<parent>
<child>
<grandchild>Jan</grandchild>
<grandchild>Kees</grandchild>
</child>
</parent>
XML;
$xml = new SimpleXMLIterator($buffer);
$recursive = new RecursiveIteratorIterator($xml);
foreach ($recursive as $tag => $object) {
if ($tag !== 'grandchild') {
continue;
}
echo $object, "\n";
}
$stack = [new SimpleXMLElement($buffer)];
while ($has = array_pop($stack)) {
foreach ($has as $tag => $object) {
if ($tag !== 'grandchild') {
$stack[] = $object;
continue;
}
echo $object, "\n";
}
}