提问人:doziem 提问时间:5/7/2022 最后编辑:doziem 更新时间:5/8/2022 访问量:158
Java - 更新大型 XML 文件中的元素
Java - Update Elements in Large XML Files
问:
我使用非常大的 XML 数据集 (1 GB+),并且需要回溯和更新每个节点的特定元素,具体取决于后面其他元素的值。
例如,在此记录/节点中:
<user>
<role>Associate</role>
<team>Hufflepuff</team>
<experience>7</experience>
</user>
由于“经验”大于 5 年,因此需要将角色从“助理”更新为“高级”。
我想避免通过 DOM 将整个文件加载到内存中。
理想情况下,我会处理 XML 中的每个“用户”,并将数据逐个附加到一个新的 XML 文件中。我首先使用 StAX 在流中进行处理,但我不知道如何将每个 XMLEventWriter 事件内容转换为可用的 DOM 文档,该文档写入 XML 文件并在之后从内存中清除。
如果描述有任何不清楚的地方,请告诉我。对此的任何帮助将不胜感激。
谢谢。
答:
0赞
Michael Kay
5/8/2022
#1
在 XSLT 3.0 中使用流式处理,您可以执行以下操作
<xsl:template match="user" mode="streamed">
<xsl:apply-templates select="copy-of(.)" mode="unstreamed"/>
</xsl:template>
在非流式处理模式下,您可以将(复制的)元素作为内存中的子树进行处理,而没有流式处理限制。user
我对 SAX 也做了同样的事情;当您命中 startElement 事件以开始构建树时,当相应的 endElement 事件发生时,以您喜欢的任何方式处理该树时,这很容易。user
我不会为此使用像 StAX 这样的拉取 API。我相信这是可以做到的,但可能需要更多的努力。
评论
0赞
doziem
5/8/2022
感谢您的回复。我目前不熟悉使用 XSLT,尽管我知道它非常流行,如果它在这种情况下提供最佳解决方案,那么学习它就可以了。我确实想先问几个问题。在更新前一个元素之前,当在节点中找到具有特定值的元素时,将进行大量的中间 Java 处理。例如,如果“experience”和“team”与某个值匹配,请进行 Database 调用,然后在替换原始元素之前处理返回的值。你仍然认为 XSLT 会成为这项工作的工具吗?
0赞
Michael Kay
5/8/2022
对不起,但我不认为根据一段需求陈述对应用程序架构和技术选择提出建议是一种专业的方法。有太多的变量:项目规模、可用技能、时间表和成本等。我会毫不犹豫地自己在 XSLT 中这样做,但这并不能使它成为每个人的正确选择。
0赞
doziem
5/8/2022
这很有帮助。我想知道的主要事情是 XSLT 是否允许与 Java 处理混合,听起来确实如此。我会把这当作一个潜在的选择来研究。谢谢,迈克尔。
评论