我正在使用JAXB作为编组人员。
我有一个包含字符串列表和其他属性的对象。我想将列表内容编组为单独的标记。
我有代码List<String> items
。如果我在列表中添加字符串“apple”,“banana”,“orange”,我想在编组时得到的xml是:
<items>
<apple/>
<banana/>
<orange/>
</items>
这可行吗?或者,为了获得该结果,我如何更改对象?
(抱歉格式化,我无法做得更好)
答案 0 :(得分:1)
我的建议是不要这样做。相反,您的XML消息如下(这将使每个人都更容易处理您的XML):
<items>
<item>apple</item>
<item>banana</item>
<item>orange</item>
</items>
好的,你决定不遵循我的建议:)。以下是如何做到这一点:
创建一个XmlAdapter
,可以将String
转换为org.w3c.dom.Element
的实例,其名称等于String
。
import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.parsers.*;
import org.w3c.dom.*;
public class StringAdapter extends XmlAdapter<Object, String> {
private Document document;
@Override
public String unmarshal(Object v) throws Exception {
Element element = (Element) v;
return element.getTagName();
}
@Override
public Object marshal(String v) throws Exception {
return getDocument().createElement(v);
}
private Document getDocument() throws Exception {
if(null == document) {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
document = db.newDocument();
}
return document;
}
}
注明List<String>
字段/属性,@XmlJavaTypeAdapter
指向您的XmlAdapter
和@XmlAnyElement
注释。
import java.util.*;
import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
@XmlRootElement
public class Items {
private List<String> items = new ArrayList<String>();
@XmlAnyElement
@XmlJavaTypeAdapter(StringAdapter.class)
public List<String> getItems() {
return items;
}
}
要提高效果,请确保您的XmlAdapter
拥有Document
的实例并在XMLAdapter
上设置Marshaller
以使其成为有状态以避免需要每次调用XmlAdapter
时重新创建它。
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Items.class);
Items items = new Items();
items.getItems().add("apple");
items.getItems().add("banana");
items.getItems().add("orange");
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.setAdapter(new StringAdapter());
marshaller.marshal(items, System.out);
}
}