我有一个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的标准方法吗?

最佳答案

以@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对象,这可能会出现问题,因此我将检查添加到了方法中

10-08 20:10