2012-09-14 3 views
4

개체에 추가 할 하위 트리 하나가 있으며 JAXB 마샬을 모든 트리를 단일 트리로 만듭니다 (적절한 태그 포함).). 그러나 현재 하위 트리의 루트 태그가 다른 객체의 태그로 바뀌 었습니다.JAXB : 개체에 하위 트리를 추가하고 전체 트리를 만드는 방법

불행히도 원래 코드를 게시 할 수 없으므로 테스트 코드에서 문제를 재현했습니다. 이 벙어리를 찾으면).

아이디어는 내가 출력의 구조는 다음과 같은 것이있다 :

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<ns2:Root xmlns:ns2="urn:my:foo:bar:1.0" xmlns:ns3="urn:other:foo:bar:1.1"> 
    <Content> 
     <Header> 
      <ns3:Leaf/> 
     </Header> 
    </Content> 
</ns2:Root> 

하지만 현재 내가 할 모든이있다 :

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<ns2:Root xmlns:ns2="urn:my:foo:bar:1.0" xmlns:ns3="urn:other:foo:bar:1.1"> 
    <Content> 
     <Header/> 
    </Content> 
</ns2:Root> 

나는 두 XSD의 필요한 모든 클래스를 생성 할 필요를 , 그래서 그 편이 좋다. (하지만이 클래스들은 생성되었으므로 수정할 수 없다.) 당신이 3 "marshallable"클래스를 찾아 그 코드에서

package foo.bar; 

import java.io.OutputStream; 

import javax.xml.bind.JAXBContext; 
import javax.xml.bind.JAXBException; 
import javax.xml.bind.Marshaller; 
import javax.xml.bind.annotation.XmlAccessType; 
import javax.xml.bind.annotation.XmlAccessorType; 
import javax.xml.bind.annotation.XmlElement; 
import javax.xml.bind.annotation.XmlRootElement; 
import javax.xml.bind.annotation.XmlType; 
import javax.xml.parsers.DocumentBuilder; 
import javax.xml.parsers.DocumentBuilderFactory; 
import javax.xml.parsers.ParserConfigurationException; 

import org.w3c.dom.Document; 
import org.w3c.dom.Node; 

public class Test { 

    private JAXBContext context; 

    public Test() throws JAXBException { 
     context = JAXBContext.newInstance(RootElement.class, LeafElement.class); 
    } 

    @XmlRootElement(name = "Root", namespace = "urn:my:foo:bar:1.0") 
    @XmlAccessorType(XmlAccessType.FIELD) 
    @XmlType(name = "Root", propOrder = { "content" }) 
    public static class RootElement { 
     @XmlElement(name = "Content") 
     protected ContentElement content; 

     public ContentElement getContent() { 
      return content; 
     } 

     public void setContent(ContentElement content) { 
      this.content = content; 
     } 
    } 

    @XmlRootElement 
    @XmlAccessorType(XmlAccessType.FIELD) 
    @XmlType(name = "Content", propOrder = { "dummy" }) 
    public static class ContentElement { 
     @XmlElement(name = "Header") 
     protected Object dummy; 

     public Object getDummy() { 
      return dummy; 
     } 

     public void setDummy(Object dummy) { 
      this.dummy = dummy; 
     } 
    } 

    @XmlRootElement(name = "Leaf", namespace = "urn:other:foo:bar:1.1") 
    @XmlAccessorType(XmlAccessType.FIELD) 
    @XmlType(name = "Leaf") 
    public static class LeafElement { 

    } 

    public Node marshal(Object obj) throws JAXBException { 
     DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
     dbf.setNamespaceAware(true); 
     Document doc = null; 
     try { 
      DocumentBuilder db = dbf.newDocumentBuilder(); 
      doc = db.newDocument(); 
     } catch (ParserConfigurationException ex) { 
      throw new JAXBException(ex); 
     } 

     Marshaller m = context.createMarshaller(); 
     m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); 
     m.marshal(obj, doc); 
     return doc.getDocumentElement(); 
    } 

    public void marshal(Object obj, OutputStream stream) throws JAXBException { 
     Marshaller m = context.createMarshaller(); 
     m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); 
     m.marshal(obj, stream); 
    } 

    public void test() throws JAXBException { 
     RootElement root = new RootElement(); 
     ContentElement content = new ContentElement(); 
     root.setContent(content); 
     LeafElement leaf = new LeafElement(); 
     content.setDummy(marshal(leaf)); 
     marshal(root, System.out); 
    } 

    public static void main(String[] args) throws JAXBException { 
     new Test().test(); 
    } 

} 

: 여기

두 번째 XML을 생성하는 샘플 코드 (잘못된)입니다

  1. RootElement
  2. ContentElement
  3. LeafElement.

첫 번째 두 클래스는 샘플 코드에서 설명한대로 (네임 스페이스가있는) 하나의 XSD에서 가져오고 마지막 두 개는 다른 네임 스페이스와 함께 다른 XSD에서옵니다.

지금까지이 문제를 해결하기 위해 ContentElement에 dummy으로 설정된 추가 클래스를 만들고 그 자체가 LeafElement를 보유하여 JAXB가 적절한 intermdiate 노드를 만들도록했습니다. 그러나이 솔루션은 JAXB가 이러한 문제를 처리 할 수있는 방법을 제공하기를 기대하면서 실제로보기 흉한 것이 었습니다.

더 많은 정보가 필요하거나 제 질문을 재구성해야한다면 주저하지 마십시오. 나는 문제를 간단한 단어로 설명하기가 힘듭니다.

  • 내가 RootElement, ContentElement에 수정할 수 없습니다 없으며 어떤 요소 클래스를 변경할 수없는 경우 LeafElement
  • 내가 JAXB

답변

1

보다 다른 뭔가를 사용할 수 없습니다, 당신은해야합니다

제약 조건은 다음과 같습니다 잎에 홀더 객체를 생성합니다. 당신이 자바에서 4 개 클래스를 가지고 있어야하므로

@XmlRootElement 
@XmlAccessorType(XmlAccessType.FIELD) 
public static class LeafElementHolder { 
    @XmlAnyElement 
    private Object leaf; 

    public Object getLeaf() { 
     return leaf; 
    } 

    public void setLeaf(Object leaf) { 
     this.leaf = leaf; 
    } 
} 

당신은 XML의 4 개 요소가() 메소드

LeafElement leaf = new LeafElement(); 
    LeafElementHolder holder = new LeafElementHolder(); 
    holder.setLeaf(leaf); 
    content.setDummy(marshal(holder)); 

상황

public Test() throws JAXBException { 
    context = JAXBContext.newInstance(RootElement.class, LeafElement.class, LeafElementHolder.class); 
} 

에이 클래스를 추가하고 테스트에 사용합니다.

ns2:Root 
    ns2:Content 
    ns2:Header 
     ns3:Leaf 
관련 문제