我有一个XML,其中一些常见的部分包含了一个可以以任何方式改变的特定部分。
例如,我必须管理这两个XML(简化):
...
<xml>
<common>
<data1>1</data1>
<data2>2</data2>
</common>
<specific>
<specific-info>
<color>blue</color>
</specific-info>
</specific>
</xml>
...
这一个:
...
<xml>
<common>
<data1>33</data1>
<data2>42</data2>
</common>
<specific>
<another-info>
<age>42</age>
</another-info>
</specific>
</xml>
...
所以我继承了这个代码(简化),使用JAXB,它可以工作:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {})
@XmlRootElement(name = "xml")
public class Specific{
@XmlElement(name = "common", required = true)
protected CommonData common;
@XmlElement(name = "specific")
protected SpecificInfo specificInfo;
@XmlElement(name = "specific")
protected AnotherInfo anotherInfo;
// getters and setters
}
问题在于,当一种新的信息到达时,我要添加具有相同名称的新XMLElement,我认为它闻起来......而且他们也是吸气剂的每一个的设定者。
还有另一种方式可以买得起吗?这是用JAXB打开包装XML的标准方法吗?
答案 0 :(得分:1)
如果我了解您的需求,您希望能够将其他元素的内容添加到<specific/>
中吗?
所以也许您可以根据想要捕捉的结构来查看@XmlAnyElement。
您可能对lax属性感兴趣,目的是保留specificInfo和anotherInfo
的处理@XmlAnyElement(lax="true")
public Object[] others;
答案 1 :(得分:1)
在@fisc显示我的方式中,我在我的bean @XmlAnyElement中使用了他的方式:
@XmlAnyElement(lax=true)
public Object[] others;
将xml的特定部分作为xml DOM对象获取,并使用此方法获取实际对象,而不是xml中任何内容的DOM表示:
@SuppressWarnings("unchecked")
public <T> T getOthersParsedAs(Class<T> clazz) throws JAXBException{
JAXBContext context = JAXBContext.newInstance(clazz);
Unmarshaller unmarshaller = context.createUnmarshaller();
T res = (T) unmarshaller.unmarshal((Node)others[0]);
if (res instanceof JAXBElement){
res = (T)JAXBIntrospector.getValue(res);
}
return res;
}
这样我就无法得到它们:
Specific spec = ...
SpecificInfo info = spec.getOthersParsedAs(SpecificInfo.class);
或:
AnotherInfo info = spec.getOthersParsedAs(AnotherInfo .class);
<强>更新强>:
我已经完成了一个方法,可以在该节点中向该xml插入任何对象(丑陋但在同一方法中显示所有代码):
public <T> void setOthersInXML(T data) throws JAXBException, ParserConfigurationException{
JAXBContext context = JAXBContext.newInstance(data.getClass());
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db= dbf.newDocumentBuilder();
Document document = db.newDocument();
Marshaller marshaller = context.createMarshaller();
marshaller.marshal(data, document);
others = new Object[]{document.getDocumentElement()};
}
并且像二传手一样使用。
再次编辑
因为我发现了一个问题:如果类没有很好地定义XMLRootElement getOthersParsedAs将返回一个JAXBElement对象,这可能会有问题,所以我已经将检查添加到方法