2009-11-21 4 views
18

내가 직면하는 문제는 하나의 XML 파일에 많은 객체 목록을 정렬하는 방법인데, 그렇게 큰 경우 전체 목록을 한 번에 마샬링 할 수 없습니다. 이러한 객체를 청크로 반환하는 메서드가 있지만 JAXB를 사용하여 이러한 객체를 마샬링합니다. marshaller는 이러한 객체가 루트 요소가 아니라는 예외를 반환합니다. 이것은 한 단계에서 전체 문서를 마샬링하려는 정상적인 경우에는 정상이지만 JAXB_FRAGMENT 속성을 true로 설정하면 발생합니다.JAXB Marshaller를 사용하여 큰 파일을 스트리밍하는 방법은 무엇입니까?

이것은 원하는 XML 출력 :

<rootElem> 
    <startDescription></startDescription> 
    <repeatingElem></repeatingElem> 
    <repeatingElem></repeatingElem>... 
</rootElem> 

그래서 나는 그가의 닫는 태그를 작성합니다 전에 동적으로 마샬에 공급하는 repeatingElements의 다음 청크를로드 청취자의 어떤 종류를 필요로 가정 rootElement. 그러나 그것을하는 방법? 지금까지는 JAXB 만 사용하여 작은 파일을 마샬링했으며 JAXB 설명서는 해당 사용 사례에 대한 많은 힌트를 제공하지 않습니다.

답변

-8

JAXB에 대해 잘 모르기 때문에 도움을받을 수 없습니다. 하지만 괜찮으 시다면 제안이 있습니다.

XML을 작성하는 것이 XML을 읽는 것보다 훨씬 쉽기 때문에 문제를 해결할 때 "저수준"접근 방식을 사용하는 것이 좋습니다. 사용 가능한 XML 용 오픈 소스 라이브러리 중 하나를 사용하여 직접 마샬 러를 작성하십시오. 나는 당신이 원하는 것을 쉽게 할 수 있다고 생각한다 dom4j.

9

발견 한 것처럼 클래스에 @XmlRootElement 주석이 없으면 해당 클래스의 인스턴스를 마샬 러에게 전달할 수 없습니다. 그러나이 문제를 해결하는 쉬운 방법이 있습니다. 객체를 JAXBElement에 랩핑 한 다음 마샬 러에게 전달합니다.

지금 JAXBElement 오히려 서투른 짐승이지만, 그것이 무엇 것은 요소 이름과 일반적으로 @XmlRootElement 주석에 포함된다 당신이 마샬링 할 개체, 정보의 네임 스페이스가 포함되어 있습니다. 이름과 네임 스페이스가있는 한 JAXBElement을 작성하여 POJO를 랩핑하고 마샬링 할 수 있습니다.

POJO가 XJC에 의해 생성 된 경우 클래스가 생성되며 여기에는 JAXBElement 래퍼를 작성하는 팩토리 메소드가 포함되어있어 작업이 좀 더 수월합니다.

반복 내부 요소에 대해서는 여전히 JAXB_FRAGMENT 속성을 사용해야합니다. 그렇지 않으면 JAXB는 매번 XML 프롤로그와 같은 요소를 생성하므로 원하지 않습니다.

15

나는 이것이 낡은 질문이라는 것을 알고 있지만 또 다른 비슷한 질문이 중복 된 것을 발견 할 때 찾아왔다.

@skaffman이 제시 하듯이 JAXB_FRAGMENT을 사용하여 마샬링하고 JAXBElement로 객체를 래핑하려고합니다. 그런 다음 반복되는 요소의 각 인스턴스를 반복해서 마샬링합니다. 기본적으로 이것은 대략 다음과 같은 것을 원하는 것처럼 들린다.

public class StreamingMarshal<T> 
{ 
    private XMLStreamWriter xmlOut; 
    private Marshaller marshaller; 
    private final Class<T> type; 

    public StreamingMarshal(Class<T> type) throws JAXBException 
    { 
     this.type = type; 
     JAXBContext context = JAXBContext.newInstance(type); 
     Marshaller m = context.createMarshaller(); 
     m.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE); 
    } 

    public void open(String filename) throws XMLStreamException, IOException 
    { 
     xmlOut = XMLOutputFactory.newFactory().createXMLStreamWriter(new FileOutputStream(filename)); 
     xmlOut.writeStartDocument(); 
     xmlOut.writeStartElement("rootElement"); 
    } 

    public void write(T t) throws JAXBException 
    { 
     JAXBElement<T> element = new JAXBElement<T>(QName.valueOf(type.getSimpleName()), type, t); 
     marshaller.marshal(element, xmlOut); 
    } 

    public void close() throws XMLStreamException 
    { 
     xmlOut.writeEndDocument(); 
     xmlOut.close(); 
    } 
} 
+0

생성자에 marshaller를 설정해야한다. this.marshaller = m; –

관련 문제