如何从巨大 (>2gb) XML 文件中删除节点?

如何从巨大 (>2gb) XML 文件中删除节点?

我正在处理几个巨大的 (>2gb) XML 文件,它们的大小导致了问题。

(我的应用程序在 PHP 脚本中使用 XMLReader 来解析较小的约 500mb 文件,效果很好,但 XMLReader 不会打开这些大文件。)

所以 - 我的想法是消除我知道不需要的文件的大父节点。

例如,如果文件的结构如下所示:

<record id="1">
    <a>
        <detail>blah</detail>
        ....
        <detail>blah</detail>
    </a>
    <b>
        <detail>blah</detail>
        ....
        <detail>blah</detail>
    </b>
    <c>
        <detail>blah</detail>
        ....
        <detail>blah</detail>
    </c>
</record>
...
<record id="999999">
    <a>
        <detail>blah</detail>
        ....
        <detail>blah</detail>
    </a>
    <b>
        <detail>blah</detail>
        ....
        <detail>blah</detail>
    </b>
    <c>
        <detail>blah</detail>
        ....
        <detail>blah</detail>
    </c>
</record>

<a>出于我的目的 - 我只需要父节点中的数据每条记录。如果我可以消除父节点<b>并且<c> 从每条记录,我可以大幅减小文件的大小,因此它足够小,可以正常使用。

做这样的事情最好的方法是什么?

我尝试过的大多数“XML 感知”实用程序都会对这么大的文件感到窒息,所以我希望我可以使用sed或 之类的东西来做到这一点grep

答案1

您可以使用 awk:

$cat my.xml | awk '/<b>/{hide=1} /<\/record>/ {hide=0} {if (hide==0) print;}' >mynew.xml

这将隐藏自包含行以来的所有内容<b>,并以包含行开始显示</record>

根据您的评论,如果您的 XML 是一大行 - 只需将其拆分为几行,并在完成转换后删除换行符。

$cat my.xml|sed 's/>/>\n/g'| awk ....... | tr -d '\n' >.....

扔掉 xml,开始使用 YAML 或 JSON!

答案2

就我个人而言,我会在 C 中做一些事情(在汇编之前可能处于最低级别)并使用 libxml 循环遍历所有节点。

这里有些例子 :http://www.xmlsoft.org/examples/

使用 GCC 编译您的代码。

相关内容