Java 使用STAX修改嵌套的XML,并针对巨大的XML进行写回—大约6 GB

Java 使用STAX修改嵌套的XML,并针对巨大的XML进行写回—大约6 GB,java,xml,stax,Java,Xml,Stax,我是java的初学者,一直在编写一个代码来解压缩一个包含大约100000个XML文件的zip文件,然后将这些文件合并成一个XML文件,这样我就可以处理一个文件而不是加载这么多文件。 我解压缩了该文件并将其合并为1个文件,并使用DOM解析器进行解析,但现在我需要修改这个合并的XML文件,然后将其写回1个文件。我可以使用DOM解析器和StringBuilder完成这项工作,但StringBuilder似乎无法处理这个大文件,因为它会导致java堆空间错误 随着我进一步研究,我了解到STAX解析器可能

我是java的初学者,一直在编写一个代码来解压缩一个包含大约100000个XML文件的zip文件,然后将这些文件合并成一个XML文件,这样我就可以处理一个文件而不是加载这么多文件。 我解压缩了该文件并将其合并为1个文件,并使用DOM解析器进行解析,但现在我需要修改这个合并的XML文件,然后将其写回1个文件。我可以使用DOM解析器和StringBuilder完成这项工作,但StringBuilder似乎无法处理这个大文件,因为它会导致java堆空间错误

随着我进一步研究,我了解到STAX解析器可能非常适合处理性能更好的大型文件

我已经阅读了多篇文章和教程,但还不能写出满足我要求的代码。 因此,我的XML有多个标记,合并后我有一个类似这样的结构:

<Items>
   <Item >
      <Tag1>
</Tag1>
         <Tag2>
</Tag2>
            <Images>
               <Image>
                  <width>200</width>
                  <height>200</height>
                  <url>xyz.com</url>
                  <action>update</action>
               </Image>
               <Image>
                  <width>400</width>
                  <height>600</height>
                  <url>xyz.com</url>
                  <action>update</action>
               </Image>
            </Images>
   </Item>
   <Item >
      <Tag1>
</Tag1>
         <Tag2>
</Tag2>
            <Images>
               <Image>
                  <width>100</width>
                  <height>400</height>
                  <url>abc.com</url>
                  <action>update</action>
               </Image>
               <Image>
                  <width>400</width>
                  <height>200</height>
                  <url>xyz.com</url>
                  <action>update</action>
               </Image>
            </Images>
   </Item>
</Items>

200
200
xyz.com
更新
400
600
xyz.com
更新
100
400
父域
更新
400
200
xyz.com
更新
我的要求是检查图像标签下的宽度和高度是否大于某个值,然后仅获取图像标签,否则将其从图像部分删除。 同样,我需要从文件中删除一些其他标记,并且在所有处理完成后,返回整个XML文件并进行更改


我阅读了许多有关STAX实现的文章,但我不清楚如何访问图像标记,它是根标记的曾孙。

使用XSLT 3.0流式处理非常简单:

<xsl:mode streamable="yes" on-no-match="shallow-copy"/>
<xsl:template match="Image">
  <xsl:variable name="image" select="copy-of(.)"/>
  <xsl:sequence select="$image[width*height gt 100000]"/>
</xsl:template>

当然,你可以在这里使用任何关于宽度和高度的谓词。当且仅当谓词为true时,样式表才会输出图像


但是,如果您有6Gb的XML分布在100K文件上,那么我不知道为什么要在处理之前将它们连接起来。这将比单独处理它们(也可以用几行XSLT代码完成)占用更多的内存。

谢谢Michael,我不确定XSLT,我现在正在探索这一点。关于连接文件,我使用这些文件的系统必须首先加载所有单独的文件,然后开始处理它们,所以我希望系统通过不单独加载文件而只加载一个大文件来节省一些性能,在相同的过程中,我还希望通过删除不必要的标记来缩短文件。我无法将XSLT模板保存在硬盘驱动器中将在外部应用程序中作为插件部署此代码。我正在尝试在Eclipse项目的一个文件夹中创建模板。我正在创建扩展名为.xsl的文件,对吗?实际上,我在模板的第一行遇到了错误:在这一行找到了多个注释:-元素“xsl:mode”的前缀“xsl”没有绑定。-没有语法约束(DTD或XML模式)。我是否采取了正确的方法?我对这一切都很陌生,请原谅我问这个问题太傻了。XSLT有初学者的问题,如果你不能按照标准教程解决这些问题,那么请提出一个单独的问题。任何XSLT教程都将向您展示XSLT样式表的基本样板结构,包括“xsl”前缀的名称空间声明。请注意,此样式表需要XSLT 3.0,默认情况下Eclipse不支持XSLT 3.0;我认为目前唯一支持流媒体功能的处理器是Saxon EE。感谢您的指导,但我现在正处于最后期限,因为XSLT对我来说是全新的,所以我将花时间来完成它。也不确定我的应用程序是否与相同的同步。当我正在研究时,是否也可以对STAX提出一些建议,因为我已经在朝着这个方向努力,对我来说,完成它可能会更容易、更快。我们都知道,花时间学习一种比我们已经知道的更好的工具是一个好主意,我很同情你。但我不会在5分钟内为你写50行代码,对不起!