4

假设我想使用XOM将大量搜索结果作为 XML 输出到 PrintWriter 或 OutputStream 中。生成的 XML 如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<resultset>
    <result>
       [child elements and data]
    </result>
    ...
    ...
    [1000s of result elements more]
</resultset>

因为生成的 XML 文档可能很大(可能有数百兆字节),所以我想以流方式输出它(而不是在内存中创建整个 Document 然后再写入)。

一次输出一个的粒度<result>是可以的,所以我想一个<result>接一个的生成,写入到流中。换句话说,我只想做类似这样的伪代码(启用自动刷新,所以不用担心):

open stream/writer
write declaration
write start tag for <resultset>
while more results:
    write next <result> element
write end tag for <resultset> 
close stream/writer

我一直在看Serializer,但是必要的方法,,,writeStartTag(Element)writeEndTag(Element)write(DocType)保护的,而不是公开的!除了继承 Serializer 以便能够使用这些方法,或者将开始和结束标记作为字符串直接写入流中,完全绕过 XOM 之外,没有其他方法吗?(在这个简单的例子中后者不会太糟糕,但在一般情况下它会变得非常丑陋。)

我错过了什么还是 XOM 不是为此而生的?

使用dom4j,我可以轻松地做到这一点XMLWriter- 它具有采用WriterorOutputStream和方法writeOpen(Element)writeClose(Element)的构造函数writeDocType(DocumentType)。与 XOM相比Serializer,其中唯一的公共write方法是采用整体的方法Document

(这与我关于XOM 是强有力竞争者的最佳 dom4j 替代品的问题有关。)

4

2 回答 2

7

我遇到了同样的问题,但发现执行您提到的选项和子类 Serializer 非常简单,如下所示:

public class StreamSerializer extends Serializer {

    public StreamSerializer(OutputStream out) {
        super(out);
    }

    @Override
    public void write(Element element) throws IOException {
        super.write(element);
    }

    @Override
    public void writeXMLDeclaration() throws IOException {
        super.writeXMLDeclaration();
    }

    @Override
    public void writeEndTag(Element element) throws IOException {
        super.writeEndTag(element);
    }

    @Override
    public void writeStartTag(Element element) throws IOException {
        super.writeStartTag(element);
    }

}

然后你仍然可以利用各种 XOM 配置,如 setIdent 等,但像这样使用它:

Element rootElement = new Element("resultset");
StreamSerializer serializer = new StreamSerializer(out);
serializer.setIndent(4);
serializer.writeXMLDeclaration();
serializer.writeStartTag(rootElement);
while(hasNextElement()) {
    serializer.write(nextElement());
}
serializer.writeEndTag(rootElement);
serializer.flush();
于 2009-09-25T22:53:20.923 回答
5

据我所知,XOM 不直接支持流式传输。

当我想流式传输我的 XML 文档时,我使用的是NUX,它具有 Streaming XML Serializer,类似于 XOM 中的标准 Serializer 类。NUX 与 XOM 兼容。我下载了 NUX 源,提取了几个 NUX 类(StreamingSerializer 接口、StreamingXMLSerializer——适用于 XOM 文档、StreamingVerifier 和 NamespacesInScope),将它们放入我的项目中,它就像一个魅力。太糟糕了,这不是直接在 XOM 中 :-(

NUX 是 XOM 非常好的伴侣:http ://acs.lbl.gov/software/nux/ ,工作镜像下载:nux-1.6.tar.gz

API 链接: http: //acs.lbl.gov/software/nux/api/nux/xom/io/StreamingSerializer.html

这是示例代码(方法按顺序调用:start(), n* nextResult(), finish(), 序列化程序是来自 NUX 的 StreamingXMLSerializer):

void start() {
    serializer.writeXMLDeclaration();

    Element root = new Element("response");
    root.addAttribute(new Attribute("found", Integer.toString(123)));
    root.addAttribute(new Attribute("count", Integer.toString(542)));

    serializer.writeStartTag(root);

    serializer.flush();
}

void nextResult(Result result) {
    Element element = result.createXMLRepresentation();
    serializer.write(element);
    serializer.flush();
}

void finish() {
    serializer.writeEndTag();
    serializer.flush();
}
于 2009-06-09T06:16:56.207 回答