【发布时间】:2009-03-18 17:40:36
【问题描述】:
我需要在 PHP 中解析相当大的 XML(比如 300 MB)。我怎样才能最有效地做到这一点?
特别是,我需要找到特定的标签并将其内容提取到一个平面 TXT 文件中,仅此而已。
【问题讨论】:
我需要在 PHP 中解析相当大的 XML(比如 300 MB)。我怎样才能最有效地做到这一点?
特别是,我需要找到特定的标签并将其内容提取到一个平面 TXT 文件中,仅此而已。
【问题讨论】:
您可以使用 PHP 的 xml parser functions 使用老式的 SAX-based parsing 方法分块读取和解析 XML。
使用这种方法,您可以解析的文档大小没有真正的限制,因为您只需一次读取和解析一个缓冲区满的文件。解析器将触发事件以指示它已找到标签、数据等。
手册中有一个simple example,它显示了如何获取标签的开始和结束。出于您的目的,您可能还想使用xml_set_character_data_handler,以便您也可以查看标签之间的文本。
【讨论】:
如果是一份或几份工作,我会使用XML Starlet。但是,如果您真的想在 PHP 端进行操作,那么我建议您将其预解析为更小的块,然后对其进行处理。如果您通过DOM 将其加载为一大块,它将占用大量 内存。还可以使用 CLI 端 PHP 脚本来加快速度。
【讨论】:
最有效的方法是创建静态 XSLT 并使用 XSLTProcessor 将其应用于您的 XML。方法名称有点误导。即使你想输出纯文本,你应该使用transformToXML(),如果你需要作为一个字符串变量,或者transformToURI(),如果你想写一个文件。
【讨论】:
这就是 SAX 的设计目的。 SAX 在读取小数据缓冲区并在遇到元素、字符数据等时触发事件的内存占用较低。
如何使用 SAX 并不总是很明显,我不是第一次使用它,但本质上你必须保持自己的状态并查看你在文档结构中的位置,所以通常你最终会出现描述您所在文档部分的变量,例如遇到特定的开始/结束元素时设置的 inFoo、inBar 等。
有一个sax解析器here的简短描述和示例
【讨论】:
拉解析是要走的路。这样它就可以节省内存并且易于处理。我一直在处理 50 Mb 或更大的文件。
【讨论】:
根据您的内存要求,您可以加载它并 parse it with XSLT(消耗内存的路线),或者您可以创建一个 forward-only cursor 并自己遍历树,打印您正在寻找的值(内存有效的路线)。
【讨论】: