[英]JAXB XMLAdapter: Is there a way to convert this method into JAXB XmlAdapter
[英]JAXB @XmlAdapter for arbitrary XML
我有一個org.w3c.dom.Element
,我從我的XmlAdapter
返回自定義@XmlElement
,我想將它作為任意XML包含在JAXB對象中(我知道我必須手工制作XSD)。 然而,JAXB抱怨道
org.w3c.dom.Element is an interface, and JAXB can't handle interfaces.
顯然,w3c XML類型不支持Java類型 ,這是一種恥辱。 但javax.xml.transform.Result
,當我使用顯然支持的javax.xml.transform.Result
時,我得到了同樣的錯誤。
如何在JAXB中包含任意XML元素作為元素?
注意:根據https://forums.oracle.com/thread/1668210我也試過了
MessageFactory factory = MessageFactory.newInstance();
message = factory.createMessage();
SOAPElement element = message.getSOAPBody().addDocument(doc);
但這也給出了同樣的錯誤。
只要將值類型指定為Object
(而不是Element
),就可以使用XmlAdapter
將域對象轉換為org.w3c.dom.Element
的實例。
以下是一個完整的例子。
java.lang.Object
類型的字段/屬性將未知內容保留為DOM節點。 您可以通過在XmlAdapter
值類型指定為Object
來在您的用例中利用它。 您需要確保從marshal
方法返回的根元素與@XmlElement
注釋定義的字段/屬性匹配。
import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.parsers.*;
import org.w3c.dom.*;
public class BarAdapter extends XmlAdapter<Object, Bar>{
private DocumentBuilder documentBuilder;
public BarAdapter() {
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
documentBuilder = dbf.newDocumentBuilder();
} catch(Exception e) {
// TODO - Handle Exception
}
}
@Override
public Bar unmarshal(Object v) throws Exception {
Bar bar = new Bar();
Element element = (Element) v;
bar.value = element.getTextContent();
return bar;
}
@Override
public Object marshal(Bar v) throws Exception {
Document document = documentBuilder.newDocument();
Element root = document.createElement("bar");
root.setTextContent(v.value);
return root;
}
}
富
@XmlJavaTypeAdapter
注釋用於引用XmlAdapter
。
import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Foo {
@XmlJavaTypeAdapter(BarAdapter.class)
private Bar bar;
}
酒吧
import javax.xml.bind.annotation.*;
@XmlAccessorType(XmlAccessType.FIELD)
public class Bar {
String value;
}
演示
由於創建DocumentBuilderFactory需要付出代價,因此我們可以通過在Marshaller上設置實例來利用JAXB處理XmlAdapter的有狀態實例的能力。
import java.io.File;
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Foo.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("src/forum18272059/input.xml");
Foo foo = (Foo) unmarshaller.unmarshal(xml);
Marshaller marshaller = jc.createMarshaller();
marshaller.setAdapter(new BarAdapter());
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(foo, System.out);
}
}
input.xml中/輸出
<?xml version="1.0" encoding="UTF-8"?>
<foo>
<bar>Hello World</bar>
</foo>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.