在this问题中,讨论了如何使用流解析PHP中的大型XML文档,以便不必将整个文档放在内存中。
但是,XMLReader
类似乎不适合解析XML文档中的大型文本节点。由于我使用的API将base64编码的文件作为XML文档的值与一些元数据一起发送,我正在寻找一种流式传输这些文本节点的方法,而不是将值作为字符串返回:
<?php
$reader = XMLReader::open($someStream);
// $reader->read() until a node is reached
// The following puts the whole text node in memory, rather than creating a stream
$content = $reader->value;
?>
是否可以将$reader->value
转换为流?
答案 0 :(得分:0)
我所提出的是使用PHP的低级XML Parser和一些流功能。
$input = fopen('input.xml', 'r');
$output = fopen('output.txt', 'w');
stream_filter_append($output, 'convert.base64-decode');
将这些传递给创建XML Parser的类:
public function __construct($input, $output) {
// ...
$this->xml = xml_parser_create();
xml_set_object($this->xml, $this);
xml_set_element_handler($this->xml, 'start', 'end');
xml_set_character_data_handler($this->xml, 'character');
}
start
和end
方法用于在XML中查找正确的元素,character
方法将内容写入输出流:
protected function character($parser, $data)
{
if ($this->match()) {
fwrite($this->output, $data);
}
}
高效的部分是我们称之为解析器的地方,它一次只读取可管理的块:
while ($data = fread($this->input, $bufferSize = 1024)) {
xml_parse($this->xml, $data, feof($this->input) or $this->done);
}
可以在$this->done
或start
处理程序中设置end
,在我的情况下,我会在找到匹配后立即删除处理程序。
由于这些旧的php函数没有抛出,当然还是必须实现一些安全检查。