【问题标题】:Flatten the xml file展平xml文件
【发布时间】:2012-05-23 08:43:57
【问题描述】:

我想编写一个通用的 xml 解析器,它可以展平任何 xml 文件。例如

如果 xml 具有如下结构:

<A a="a1">

   <B> b </B>

   <C>

      <D> d1 </D>

      <D> d2 </D>

   </C>

   <C>

      <D> d3 </D>

   </C>

   <E> e1 </E>     

</A>

我应该得到如下输出:

a1 b d1 e1

a1 b d2 e1

a1 b d3 e1

我希望解析器是通用的,这样它就可以在不知道标签的情况下应用于任何 xml。我听说过 XSLT。但我不确定我们是否可以编写一个没有 xml 标签知识的通用 XSL。 XML 文件的大小约为 1Gb。 这个问题有通用解决方案吗?

【问题讨论】:

  • xslt 要求在执行转换之前将整个文档加载到内存中。那是一个很大的内存占用。你研究过 SAX 吗?
  • 是的,我知道 ABT SAX 解析器。但是我被困在没有任何 xml 标签的任何先前信息,甚至是根标签的情况下,无法展平嵌套的 xml。
  • @ColinD 通常 Xslt 处理器支持流式传输,因此您不必将整个文档加载到内存中。见What is the Most Efficient Java-Based XSLT Processor
  • @user1397016 使用 Xslt 并不需要了解实际标签,而是需要了解结构 - 只需使用 Location Paths,您就可以实现很多目标。
  • @Filburt 流式传输 xslt 是 xsl 规范 (2.0+) 的下一个版本正在考虑的功能。我想大多数现在做流媒体的处理器,只在特定情况下做,所以我不确定它是否可以依赖。

标签: java xml xslt xml-parsing


【解决方案1】:

使用 SAX 解析器,并保留一堆打开的元素。看到元素打开后,将它们添加到堆栈中。在文本节点上,打印堆栈,在关闭元素上,将它们从堆栈中弹出。应该是直截了当的。

【讨论】:

  • 我不认为你给出的解决方案会给出所需的输出。你能在我提出的案例上运行你的逻辑,看看它是否给出相同的输出。你的逻辑不会重复父元素。如果我在某个地方弄错了,请纠正我!
  • 好吧,正确地指定你的输出,而不是举例!在您的情况下, B 和 E 不是 父元素!
【解决方案2】:

您似乎想要的“扁平化”更像是一种“爆炸式”。您的输入是一棵树,您希望将其分解为一组记录,其中重复所有冗余数据。这不是 XSLT 的工作。从概念上讲,您必须对数据进行多次传递。首先,您必须识别所有级别的所有叶节点集合;然后你必须遍历所有可能的叶子节点组合,为每个组合输出一组完整的数据。如果您的输入约为 1GB,请为 TB 的输出做好准备。

看起来你有两个选择:

  1. 使用 SAX 将整个树加载到内存中,然后实现爆炸算法。
  2. 传递输入数据以提取结构并在每个叶节点集上建立位置光标;然后对输入进行多次传递,使用光标决定每次传递的输出。

无论哪种方式,我都不确定您所描述的实际上是您想要的。对于任何大型的多级叶节点集,组合的数量很容易成为天文数字。

【讨论】:

    猜你喜欢
    • 2012-03-02
    • 1970-01-01
    • 2022-10-07
    • 2021-10-16
    • 2014-11-09
    • 2015-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多