PHPDOM:如何以优雅的方式通过标记名获取子元素?
我正在用PHPDOM扩展解析一些XML,以便以其他形式存储数据。毫不奇怪,当我解析一个元素时,我经常需要获取某个名称的所有子元素。有一个方法PHPDOM:如何以优雅的方式通过标记名获取子元素?,php,xml,dom,Php,Xml,Dom,我正在用PHPDOM扩展解析一些XML,以便以其他形式存储数据。毫不奇怪,当我解析一个元素时,我经常需要获取某个名称的所有子元素。有一个方法DomeElement::getElementsByTagName($name),但它返回所有具有该名称的子代,而不仅仅是直接子代。还有属性DOMNode::$childNodes,但是(1)它包含节点列表,而不是元素列表,即使我设法将列表项转换为元素(2),我仍然需要检查所有这些项的名称。是否真的没有优雅的解决方案来只获取某个特定名称的子对象,或者我在文档
DomeElement::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
?>
我能想象的一种优雅的方式是使用适合该工作的过滤器。能够处理所述DOMNodeList
并(可选)接受标记名作为迭代器花园中的示例性DOMElementFilter
进行筛选的示例性标记名:
这将给出您想要的结果:
1
2
你现在可以找到了。允许任何标记名使用*
,这可能是值得的,因为getElementsByTagName(“*”
也可以。但这只是一些评论
Hier是一个在线工作使用示例:我可以想象一种优雅的方式是使用适合该工作的过滤器。能够处理所述DOMNodeList
并(可选)接受标记名作为迭代器花园中的示例性DOMElementFilter
进行筛选的示例性标记名:
这将给出您想要的结果:
1
2
你现在可以找到了。允许任何标记名使用*
,这可能是值得的,因为getElementsByTagName(“*”
也可以。但这只是一些评论
Hier是一个在线工作使用示例:简单迭代过程
$parent = $p->parentNode;
foreach ( $parent->childNodes as $pp ) {
if ( $pp->nodeName == 'p' ) {
if ( strlen( $pp->nodeValue ) ) {
echo "{$pp->nodeValue}\n";
}
}
}
简单迭代过程
$parent = $p->parentNode;
foreach ( $parent->childNodes as $pp ) {
if ( $pp->nodeName == 'p' ) {
if ( strlen( $pp->nodeValue ) ) {
echo "{$pp->nodeValue}\n";
}
}
}
我在生产中使用的解决方案:
大海捞针(DOM)
用法:
$countryNode = getAttachableNodeByAttributeName($countriesNode, 'country', 'iso', 'NL');
使用国家/地区iso代码“NL”,通过指定属性iso
从父国家/地区节点返回DOM元素,基本上与实际搜索类似。通过数组/对象中的名称查找某个国家
另一个使用示例:
$productNode = getAttachableNodeByAttributeName($products, 'partner-products');
返回仅包含单个(根)节点的DOM节点元素,不按任何属性进行搜索。
注意:为此,您必须确保根节点根据元素的标记名是唯一的,例如,国家->国家[ISO]
-国家
节点此处是唯一的,并且是所有子节点的父节点。生产中使用的我的解决方案:
大海捞针(DOM)
用法:
$countryNode = getAttachableNodeByAttributeName($countriesNode, 'country', 'iso', 'NL');
使用国家/地区iso代码“NL”,通过指定属性iso
从父国家/地区节点返回DOM元素,基本上与实际搜索类似。通过数组/对象中的名称查找某个国家
另一个使用示例:
$productNode = getAttachableNodeByAttributeName($products, 'partner-products');
返回仅包含单个(根)节点的DOM节点元素,不按任何属性进行搜索。
注意:为此,您必须确保根节点根据元素的标记名是唯一的,例如国家->国家[ISO]
-国家
节点是唯一的,并且是所有子节点的父节点。oth,只需使用上下文节点运行DOMXPath::query
。(或者添加整个文档,并查询/a[1]/b
)在现实生活中,我解析相当大的文件,所以我使用DOMReader
和expand()
方法逐块解析它们。不幸的是,副作用是我没有DOMDocument
,只有DOMElement
的许多实例,我无法为它们优雅地构造DOMXPAth
。。。为什么这一切都考虑得这么糟糕!?!我想避免将DOMElment
s再次转换为SimpleXML
,但我离这个决定越来越近了……哦,只需使用上下文节点运行DOMXPath::query
。(或者添加整个文档,并查询/a[1]/b
)在现实生活中,我解析相当大的文件,所以我使用DOMReader
和expand()
方法逐块解析它们。不幸的是,副作用是我没有DOMDocument
,只有DOMElement
的许多实例,我无法为它们优雅地构造DOMXPAth
。。。为什么这一切都考虑得这么糟糕!?!我想避免将DOMElment
s再次转换为SimpleXML
,但我离这个决定越来越近了。。。