代码之家  ›  专栏  ›  技术社区  ›  Jonik

如何使用XOM传输XML数据?

  •  4
  • Jonik  · 技术社区  · 17 年前

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

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

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

    输出1的粒度 <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) 是受保护的,不是公开的!除了将序列化程序子类化以使用这些方法,或者手动将开始和结束标记作为字符串直接写入流中,完全绕过XOM之外,没有其他方法了吗?(在这个简单的例子中,后者不会太糟糕,但在一般情况下,它会变得非常丑陋。)

    具有 dom4j 我可以很容易地使用 XMLWriter -它的构造函数采用 Writer OutputStream ,以及方法 writeOpen(Element) , writeClose(Element) writeDocType(DocumentType) 等。与XOM的相比 序列化程序 write 方法是一种需要一个整体的方法 Document

    (这与 my question about the best dom4j replacement

    2 回复  |  直到 9 年前
        1
  •  7
  •   kostmo    13 年前

    我也遇到了同样的问题,但发现做您提到的选项和子类序列化程序非常简单,如下所示:

    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);
        }
    
    }
    

    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();
    
        2
  •  5
  •   Peter Å tibraný    16 年前

    据我所知,XOM不支持直接流媒体。

    当我想流式处理XML文档时,我使用的是 NUX ,它具有流式XML序列化程序,类似于XOM中的标准序列化程序类。NUX与XOM兼容。我下载了NUX源代码,提取了几个NUX类(StreamingSerializer接口、StreamingXMLSerializer——适用于XOM文档、StreamingVerifier和NamespacesInsScope),将它们放在我的项目中,它就像一个符咒一样工作。太糟糕了,这不是直接在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()

    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();
    }
    
    推荐文章