我有一个子树,我想将它附加到一个对象上,并使 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 个“可编组”类:
RootElement
,ContentElement
和LeafElement
.
前两个类来自一个 XSD(具有给定的命名空间),最后一个来自另一个 XSD(具有另一个命名空间),如示例代码所示。
到目前为止,我发现要解决这个问题的方法是创建一个附加类,该类将设置为dummy
ContentElement 上的内容,并且本身将包含 LeafElement,以便 JAXB 创建适当的中间节点。但是我发现这个解决方案非常丑陋,不是真正可维护的,并且希望 JAXB 有一些方法来处理这种情况。
如果您需要更多信息,或者您需要我重新提出我的问题,请不要犹豫。我很难用简单的话来解释我的问题。
约束如下:
- 我无法修改 RootElement、ContentElement 或 LeafElement
- 我不能使用除 JAXB 以外的其他东西