我有以下代码,它将根据某个子值从XML文件中检索数据。
<?php
$dom = new DOMDocument();
$dom->load('file.xml');
$xpath = new DOMXPath($dom);
echo $xpath->evaluate('string(//Book[BookCode = "AD0WNR"] /Subject)');
?>
如果我有几行,代码就可以了。但主要的xml文件超过200mb,它不会检索任何东西。你能告诉我我做错了什么吗?小文件和大文件都具有相同的结构。
答案 0 :(得分:2)
为了解析像这样的大型文档,我建议使用像XMLReader这样的流式解析器,它允许您解析XML而无需立即将整个文件加载到内存中。通过使用其expand()
方法,可以轻松地将其与DOM API一起使用。
像DOM这样的基于树的解析器速度非常快,但由于必须加载整个文档,因此占用更多内存。像XMLReader这样的流式解析器可以减少内存使用量,因为您一次只能抓取一些文档,但权衡时间更长。
通过使用两者,您可以调整串联使用的方式,以便在最小化处理时间的同时获得内存限制等任何硬边界。
$dom = new DOMDocument();
$xpath = new DOMXPath($dom);
$reader = new XMLReader();
$reader->open('file.xml');
while ($reader->read()) {
if ($reader->nodeType == XMLReader::ELEMENT && $reader->name == 'Book') {
$node = $dom->importNode($reader->expand(), true);
$result = $xpath->evaluate(
'string(self::Book[BookCode = "AD0WNR"]/Subject)',
$node
);
if ($result) {
echo $result;
$reader->close();
break;
}
}
}
这是在迭代XML中的节点。每当它遇到元素<Book>
时,我们:
如果XPath表达式找到了我们正在寻找的内容:
#2和#3我们这样做是因为我们只寻找一个结果。如果您想要找到更多,请删除它们并继续运输。
(*我将XPath表达式中的初始双正斜杠替换为self::
,以作为第二个参数传递给evaluate()
的上下文节点执行操作 - 谢谢,{{3 }})