我有一个用于输入流的Go程序,即os.Stdin:一个非常大的XML文件,所以我不能一次性处理它。
我希望提取所有具有某种性质的XML元素,以便进行后处理。
我不难识别要提取的元素,并获得相关的开始和结束元素。但是,我不知道如何将整个元素转储为字符串,而不仅仅是内部XML。
例如,假设我有以下XML:
<a>
<b somethingUseful="1">
<c>Hello</c>
<d>world</d>
</b>
<e>
<foo/>
</e>
<!-- Imagine there were 1 billion lines in between -
I need to stream this! -->
<b somethingUseful="321">
<c>Hello again</c>
</b>
</a>在本例中,我希望从开始到完成输出每个<b>元素。
通过使用innerxml和DecodeElement,我能够以流媒体的方式实现这一目标:
Here comes a B:
<c>Hello</c>
<d>world</d>
Here comes a B:
<c>Hello again</c>如此接近,但它缺少了<b>标记(和属性)本身。在不牺牲解码的流特性的情况下,我还没有弄清楚如何完成最后一步。
明确地说,我想要的输出是这样的:
Here comes a B:
<b somethingUseful="1">
<c>Hello</c>
<d>world</d>
</b>
Here comes a B:
<b somethingUseful="321">
<c>Hello again</c>
</b>这里有一个操场,阐述了这个例子,以及我为实现这一目标所做的工作:
发布于 2016-11-10 11:15:47
受@nothingmuch的decoder.InputOffset用法的启发,我使用TeeReader将输入Reader分成两部分:通过解码器解析的标准和用于输出确切元素的缓冲区(在遇到元素之前和之后,该缓冲区位于decoder.InputOffset之间)。
为了最大限度地减少内存使用,缓冲区一直被清除,直到我们知道不可能匹配为止。我们保持抵消,以跟踪这一点。这种增加的复杂性是必要的,因为解码器可以在手边的令牌之前从读取器中获取字节,所以我们需要小心,不要清除我们实际需要的东西。
因此,额外的内存使用量仅限于:
下面是一个更新的操场,提供了解决方案:
发布于 2016-11-10 04:38:07
https://stackoverflow.com/questions/40517885
复制相似问题