PHP DOM:如何以一种优雅的方式通过标记名称获取子元素?

Kal*_*mar 5 php xml dom

我正在解析一些具有PHP DOM扩展名的XML,以便以其他形式存储数据。毫不奇怪,当我解析一个元素时,我经常需要获取某个名称的所有子元素。有方法DOMElement::getElementsByTagName($name),但是它返回具有该名称的所有后代,而不仅仅是直接子代。还有一个属性,DOMNode::$childNodes但是(1)它包含节点列表,而不是元素列表,即使我设法将列表项变成元素(2),我仍然需要检查所有这些列表以获取名称。真的没有一种优雅的解决方案来只获得某个特定名称的孩子,还是我在文档中缺少某些东西?

一些插图:

<?php

DOMDocument();
$document->loadXML(<<<EndOfXML
<a>
  <b>1</b>
  <b>2</b>
  <c>
    <b>3</b>
    <b>4</b>
  </c>
</a>
EndOfXML
);

$bs = $document
    ->getElementsByTagName('a')
    ->item(0)
    ->getElementsByTagName('b');

foreach($bs as $b){
    echo $b->nodeValue . "\n";
}

// Returns:
//   1
//   2
//   3
//   4
// I'd like to obtain only:
//   1
//   2

?>
Run Code Online (Sandbox Code Playgroud)

M.Z*_*.Z. 8

简单的迭代过程

$parent = $p->parentNode;

foreach ( $parent->childNodes as $pp ) {

    if ( $pp->nodeName == 'p' ) {

        if ( strlen( $pp->nodeValue ) ) {
            echo "{$pp->nodeValue}\n";
        }

    }

}
Run Code Online (Sandbox Code Playgroud)


hak*_*kre 4

我可以想象的一种优雅的方式是使用FilterIterator适合这项工作的工具。能够处理这样的一个示例DOMNodeList并且(可选地)接受标记名以作为迭代器花园DOMElementFilter中的示例 进行过滤:

$a = $doc->getElementsByTagName('a')->item(0);

$bs = new DOMElementFilter($a->childNodes, 'b');

foreach($bs as $b){
    echo $b->nodeValue . "\n";
}
Run Code Online (Sandbox Code Playgroud)

这将给出您正在寻找的结果:

1
2
Run Code Online (Sandbox Code Playgroud)

您现在可以DOMElementFilter在开发分支中找到。也许值得允许*任何标记名,因为它也是可能的getElementsByTagName("*")。但这只是一些评论。

Hier 是一个在线工作使用示例:https ://eval.in/57170