【问题标题】:STAX to modify a nested XML with conditions and write back for Huge XML- around 6 GBSTAX 使用条件修改嵌套 XML 并为巨大的 XML 写回大约 6 GB
【发布时间】:2021-07-28 01:29:18
【问题描述】:

我是 java 初学者,一直在编写代码来解压缩包含大约 100 000 个 XML 文件的 zip 文件,然后将这些文件合并为 1 个 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>

我的要求是检查图像标签下的宽度和高度是否大于某个值,然后只取图像标签,否则从图像部分删除它。 同样,我需要从文件中删除一些其他标签,一旦所有处理完成,将返回整个 XML 文件并进行更改。

我浏览了很多关于 STAX 实现的文章,但我无法弄清楚如何访问 Image 标签,它是根标签 的曾孙。

【问题讨论】:

    标签: java xml stax


    【解决方案1】:

    使用 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>
    

    当然,您可以在此处对宽度和高度使用任何谓词。当且仅当谓词为真时,样式表才会输出图像。

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

    【讨论】:

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