PHP XMLReader 获取父节点?

Posted

技术标签:

【中文标题】PHP XMLReader 获取父节点?【英文标题】:PHP XMLReader getting parent node? 【发布时间】:2009-02-04 23:03:57 【问题描述】:

使用 XMLReader 方法解析 XML 文件时,如何获取元素的父节点?

$xml = new XMLReader();
$xml->XML($xmlString);
while($xml->read())


$xml->localName; // gives tag name
$xml->value; // gives tag value

// how do I access the parent of this element 

【问题讨论】:

【参考方案1】:

简短版:您不会,至少不会直接这样做。程序员可以使用 XMLReader 将上下文编码到他们的解析算法中。

长版:php 的 XMLReader 是所谓的 pull 解析器。拉解析器与基于树/dom 的解析器的不同之处在于它们可以处理文本流。换句话说,他们可以在获得整个文档之前开始解析文档。这与 SimpleXML 或 DOMDocument 等基于树的/DOM 解析器不同,后者需要将整个文档加载到内存中才能执行任何操作。

优点是,如果您有一个 75MB 的 XML 文件,则不需要 75MB 的空闲 RAM 来处理它(就像使用基于树的解析器一样)。权衡是拉解析器永远不会有整个文档的上下文。唯一具有他们目前正在处理的任何节点的上下文。

另一种思考方式是基于树/dom 的解析器必须了解文档的每个部分,因为它不知道您要向它询问什么。但是,您和拉解析器做出了不同的安排。它会不断向您抛出节点,并由您自己处理它们的内容。

这里有一些示例代码(希望)接近您所追求的。

$xml = new XMLReader(); 
$xml->open('example.xml');
$last_node_at_depth = array();
while($xml->read())
               
    //stash the XML of the entire node in an array indexed by depth
    //you're probably better off stashing exactly what you need from
    $last_node_at_depth[$xml->depth] = $xml->readOuterXML();

    $xml->localName; // gives tag name
    $xml->value;     // gives tag value     

    //so, right now we're at depth n in the XML document.  depth n-1 
    //would be our parent node
    if ($xml->depth > 0) 
        //gives the fragment that starts with the parent node       
        $last_node_at_depth[($xml->depth-1)];   
    

【讨论】:

“如果你有一个 75MB 的 XML 文件,你就不需要 75MB 的空闲 RAM”这个说法可能有点误导。如果您对 75MB 大文件使用 file_get_contents 函数,您仍然需要 75MB 的 RAM。实际上,通过使用 DOMDocument,您将需要超过 75MB 你应该改用$xml->open('example.xml'); @Petr 我不知道 2009 年我在想什么。谢谢指正!【参考方案2】:

我已经开始使用 XMLReader 的 expand() 函数。它给出了当前 xml 标签的 DOM 表示。我在父节点上使用了 expand(),它给了我父标签的 DOM 元素,然后使用通常的 DOMDocument() 解析方式提取子值。

//usage
$xml = new XMLReader();
$xml = $xml->XML($xmlResponse);
while($xml->read())

$parent = $xml->expand();

$firstChildValue = $parent->getElementsByTagName('child')->item(0)->nodeValue;

使用扩展函数仅将 XML 的大部分内容加载到内存中,而不是将整个 XML 加载到内存中。

【讨论】:

我也使用这种方法,因为它比使用 XMLReader 读取整个文档要简单得多,但速度很慢。【参考方案3】:

我想你想要:XMLReader::moveToElement

【讨论】:

这会将您移动到属性的父元素,而不是子元素的父元素。

以上是关于PHP XMLReader 获取父节点?的主要内容,如果未能解决你的问题,请参考以下文章

PHP XMLReader 读取、编辑节点、编写 XMLWriter

深入认识XmlReader

使用 DOMDocument PHP 获取 Xpath 父节点?

如何使用simpleXML(php)通过xpath获取父节点

为啥在解析 XML 时获取空节点值

是否可以使用 xmlreader 更改节点值?