![删除大文件中的 XML 标记](https://linux22.com/image/206693/%E5%88%A0%E9%99%A4%E5%A4%A7%E6%96%87%E4%BB%B6%E4%B8%AD%E7%9A%84%20XML%20%E6%A0%87%E8%AE%B0.png)
我很难解析一个巨大的 XML 文件(大约 100GB,带有大节点)。我正在尝试通过删除不必要的标签来减小节点大小。例如,任何<text>
标签。
如果我使用本机 XML 解析器,例如xmlstarlet
xmlstarlet ed -P -d '//text' file.xml
我面临同样的问题,即内存不足。
是否有一种安全的方法(内存占用很少)来删除所有<text></text>
对而不破坏 XML 结构?
答案1
我建议你尝试一下xml_grep
,它会很慢但内存效率很高。它是perl-XML-Twig
(或xml-twig-tools
) - 用于以树模式处理大型 Xml 文档的 Perl 模块的一部分。您可以使用-v
按名称排除节点。请参阅man xml_grep
,用小输入测试您的命令。
例子:
xml_grep --nowrap -v 'text' input.xml > output.xml
或者用进度条来观看,因为这会花费很多时间:
pv input.xml | xml_grep --nowrap -v 'text' > output.xml
对于一般情况,您可以使用 Python、Perl、Java、Ruby (nokogiri) 或类似的带有一些 sax/stream 模块的语言。
答案2
以下 XSLT 3.0 样式表将完成这项工作:
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0">
<xsl:mode streamable="yes" on-no-match="shallow-copy"/>
<xsl:template match="text"/>
</xsl:template>
警告:您将需要一个流式 XSLT 处理器,这实际上可能意味着 Saxon Enterprise Edition,它是我的公司 Saxonica 的商业产品。
另请注意,处理速度可能约为 2Gb/分钟,当然取决于硬件。
另一种方法是使用类似 SAX 的 API 编写自己的代码来完成此操作。