我有一個子樹,我想附加在一個對象上,並讓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的生成所有必要的類,所以我可以在那邊(但是因爲這些類是生成的,我不能修改它們)。
這裏是一個示例代碼,產生第二XML(錯誤的):
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();
}
}
在該代碼中你會發現3 「marshallable」 類:
RootElement
,ContentElement
和LeafElement
。
前兩個類來自一個XSD(具有給定名稱空間),最後一個來自另一個XSD(具有另一個名稱空間),如示例代碼中所示。
到目前爲止,我發現解決這個問題的唯一方法就是創建一個額外的類,它將在ContentElement上設置爲dummy
,並且本身會保存LeafElement,以便JAXB創建適當的中間節點。但是我發現這個解決方案非常難看,不能真正維護,並且希望JAXB有辦法處理這種情況。
如果您需要更多信息,或者您需要我重新制定我的問題,請不要猶豫。我很難用簡單的話來解釋我的問題。
約束如下:
- 我不能修改rootElement的,ContentElement的也不LeafElement
- 我無法用別的東西比JAXB