0

我正在 Android 中开发一个应用程序,我需要遍历一个 xml 文件。

我需要从给定位置来回遍历 xml。这意味着我开始解析文件,但在每一刻我都可以停下来倒退或继续。

我正在考虑使用 DOM,通过它的 for 循环,我可以控制它并做我想做的事。但是我要解析的 xml 文件至少有 8 Mb,并且由于 DOM 非常占用内存,因此似乎不是一个好的解决方案。

解决此问题的方法是不加载整个文档进行解析。喜欢将文档分成几部分,只将一部分加载到内存中并解析。当我结束这部分时,我加载另一个。当我想倒带时也是如此。

我的问题是,我怎样才能将文件分成几部分。因为它是一个 xml 文件,而孩子们的大小不一样?

例如:

<root>
   <child time="A">
     <sub1>1</sub1>
     <sub2>2</sub2>
   </child>

   <child time="B">
     <sub1>3</sub1>
   </child>

   <child time="C">
     <sub2>4</sub2>
   </child>
</root>

如您所见,他们的孩子有不同的大小,我不知道如何以有效的方式将这样的文件分成几个部分。

谁能给我一个线索?

最好的祝福。

4

1 回答 1

2

对于 XML,您通常必须做出选择。DOM 是内存密集型的,SAX 不能倒退,手工制作的解析器创建和维护起来很繁琐。

如果你能负担得起消耗数十 MB 的内存,那就简单地使用 DOM。

SAX 和手动解析之间的决定取决于您实际需要返回的频率以及此时您是否可以承受延迟。

如果你不能,你将不得不实现一个带有预计算的手工解析器。例如,可以使用 SAX、与CountingInputStream结合使用或手动进行预计算。n您将预先计算每个-th元素的开始和结束偏移量,child并将其存储为间隔数组,如下所示:

public class Interval {
    public int startOffset;
    public int endOffset;
}

Interval[] precomputedOffsets;

的值n,即页面大小,可能是 20 左右。平衡它以控制内存消耗和返回性能之间的权衡。

现在,如果您知道需要在运行时转到 item i,您将在输入流上调用resetskip(precomputedOffsets[i / n]),并从那里手动解析i % n剩余child元素。

于 2012-06-17T08:17:53.647 回答