如何在不将文件内容加载到java的内存中的情况下替换xml文件中的字符串?

时间:2015-04-30 04:11:36

标签: java xml string fileutils string-utils

我的应用程序创建了一个非常大的xml文件(大约300K个事务)。每个事务都有大约20个xml元素。所以它创建了一个巨大的xml文件。我们没有使用JAXB或SAX或DOM来创建xml文件,因为内存是约束。现在我需要在创建xml文件后替换某些标记值。我知道要替换的内容和要替换的值。如何在不将整个文件加载到内存中的情况下替换这些变量?对于300K事务,文件大小约为600 MB。因此,我们不希望将整个文件加载到内存中以替换少量变量。

我们正在使用Java5。有没有办法可以做到?

3 个答案:

答案 0 :(得分:2)

您可以尝试VTD-XML

  • 内存效率(1.3x~1.5倍大小的XML文档)随机访问XML解析器。
  • 最快的XML解析器:在Core2 2.5Ghz桌面上,VTD-XML的性能优于DOM解析器5x~12x,每核心持续吞吐量可提供150~250 MB /秒。
  • 支持增量更新的XML解析器,能够以最高效率剪切,粘贴,拆分和组装XML文档。
  • 提供C,C ++,C#和 Java

Example modifying XML

答案 1 :(得分:1)

我在此主题上所阅读的所有内容都表明,如果不将文件加载到内存或将其传输到其他文件,则无法执行此操作。这可能是您最终需要做的事情 - 将您的源流式传输到新文件中,随时修改。

有关该流程的更多信息 - http://docs.oracle.com/javaee/5/tutorial/doc/bnbfl.html#bnbgq

我喜欢Stephen C在答案中解决问题的方式 - How to modify a huge XML file by StAX?

答案 2 :(得分:1)

您可以尝试使用XSLT 3.0(特别是Saxon-EE)进行流式转换。

我不确定“标签值”是什么意思(如果人们使用正确的术语会更容易......)但是如果你的意思是文本节点的值,那么你可以写一个像这样:

<xsl:mode streamable="yes" on-no-match="shallow-copy"/>

<xsl:template match="xyz/text()[.='old value']">
  <xsl:text>new value</xsl:text>
</xsl:template>

有进一步替换的进一步规则。当然,您也可以使用重命名或删除所选元素的规则等。