java - 通用 JAXB 到由相同 XML 包装的不同 XML

标签 java xml jaxb

我有一个 XML,其中一些公共(public)部分包装了可以以任何方式更改的特定部分。

例如,我必须管理这 2 个 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,并且我认为它闻起来......而且它们是每个信息的 getter 和 setter。

还有其他方法可以负担得起吗?这是使用 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()};
    }

并且像 setter 一样使用。

再次编辑

因为我发现了一个问题:如果类没有很好地定义,XMLRootElement getOthersParsedAs 将返回一个 JAXBElement 对象,这可能会出现问题,所以我已将检查添加到方法中

关于java - 通用 JAXB 到由相同 XML 包装的不同 XML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36034744/

相关文章:

java - JAX-B : dynamically generate element name from XMLAttribute

java - 如何在java中将多级xml扁平化为List<String xpath>?

java - 行程 : making double array String into a Map of String, 字符串(键和值)

java - Flutter 报错 Kotlin 找不到所需的 JDK 工具

xml - 如何在node.js中将数据写入xml文件

php - Xml 喊话到 mysql 数据库

java - XmlAdapter 无法与较新版本的 JAXB 一起正常工作

java - 使用 writeDouble 会产生无意义的结果

java - 每个单个实体组每秒写入 1 次的限制?

html - HTML 中的低星号