2009-06-08 1 views
4

XOM을 사용하여 엄청난 수의 검색 결과를 XML로 PrintWriter 나 OutputStream에 출력하고 싶습니다. 결과 XML은 다음과 같이 보일 것이다 :XOM을 사용하여 XML 데이터를 스트리밍하는 방법은 무엇입니까?

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

를 결과 XML 문서 (아마도 수백 메가 바이트) 큰이 될 수 있기 때문에, 내가 대신 메모리에 전체 문서를 만드는 (스트리밍 방식으로 출력 그것을 원하고 그 다음 그것을 쓰는 것).

한 번에 하나의 <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를 사용하여이 작업을 수행 할 수 있습니다 - 그것은 공공의 write 방법이 걸리는 일입니다 XOM의 Serializer에 비교하십시오 Writer 또는 OutputStream 및 방법 writeOpen(Element), writeClose(Element), writeDocType(DocumentType) 등 걸릴 생성자가 있습니다 전체 Document.

(XOM 강력한 경쟁자 곳이 my question about the best dom4j replacement 관련이있다.)

답변

8

내가 같은 문제에 달려 있지만, foun

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

} 

그런 다음 당신은 여전히 ​​등 setIdent 같은 다양한 XOM의 설정을 이용할 수 있습니다 : D는 다음과 같이 옵션을 선택하고 서브 클래스 시리얼로 언급 한 것을 할 아주 간단그러나이처럼 사용 NUX에 대한

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(); 
+0

그래, 나는이 방법이 가능해야한다고 생각했지만 결코 시도하지는 않았다. 이것을 확인해 주셔서 감사합니다! 어떤면에서는 이것이 또 다른 제 3 자 라이브러리 (Peter의 대답 참조)를 소개하는 것이 단순한 스트리밍을하는 것보다 바람직하다고 생각합니다. (그래도 XOM에는이 기본 제공 기능이 포함되어 있지 않습니다.) – Jonik

+0

두 가지 모두에 동의해야합니다. –

+0

니스. 나는 당신의 해결책을 좋아하고 다음 번에 그것을 시도 할 것입니다. –

5

지금까지 내가 아는 한, XOM 직접 스트리밍을 지원하지 않습니다.

XML 문서를 스트리밍하고 싶을 때 사용했던 것은 NUX이며 XOM의 표준 Serializer 클래스와 비슷한 Streaming XML Serializer가 있습니다. NUX는 XOM과 호환됩니다. NUX 소스를 다운로드하고 NUX 클래스 몇 개 (StreamingSerializer 인터페이스, StreamingXMLSerializer - XOM 문서, StreamingVerifier 및 NamespacesInScope)를 추출하여 프로젝트에 넣었습니다. 매력처럼 작동합니다. http://acs.lbl.gov/software/nux/ 작업, 거울 다운로드 : nux-1.6.tar.gz

링크 API에 : http://acs.lbl.gov/software/nux/api/nux/xom/io/StreamingSerializer.html 여기

샘플 코드 (방법입니다

NUX가 XOM에 아주 좋은 동반자가 :-(너무 나쁜이 XOM에 직접 아니다 순서로 호출됩니다 * 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(); 
} 
+1

업데이트 링크 : http://acs.lbl.gov/software/nux/ –

+0

@Ed : 감사합니다! 나는 대답을 업데이트 할 것이다. –

+1

또한 다운로드 링크는 사이트가 깨져서 유지가 안되기 때문에 다음과 같습니다. http://openbsd.mirrors.tds.net/pub/FreeBSD/distfiles/nux-1.6.tar.gz –