java - JAXB 可映射 XML 元素

标签 java xml jaxb marshalling xmladapter

在我的 xi-schema 的 root.class 中,元素 item 和其他对象是 itemList 的一部分:

@XmlElementRef(name = "item", namespace = "xi", type = JAXBElement.class, required = false) 
//...
protected List<Object> itemList;

我在主模式的 ObjectFactory.class 中有一些项目作为 JAXBElements,如下所示:

@XmlElementDecl(namespace = "de-schema", name = "detailedInformation", substitutionHeadNamespace = "xi", substitutionHeadName = "item")
public JAXBElement<numItemType> createDetailedInformation(numItemType num) {
    return new JAXBElement<numItemType>(_detailedInformation_QNAME, numItemType.class, null, num);
}

因此 numItemType 具有 JAXBElement 的一些属性和值 (num)。

NumItemType.class:

@XmlJavaTypeAdapter(numItemTypeAdapter.class)
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "numItemType", namespace = "xi", propOrder = {
    "num"
})

public class NumItemType {

    @XmlValue
    protected BigDecimal num;
    @XmlAttribute(name = "precision")
    protected String precision;
    @XmlAttribute(name = "decimals")
    protected String decimals;
    //... more Attributes

}

但是当 JAXB 解码 XML 文档时,它将只有元素,例如:

<detailedInformation>
    <element1>1234</element1>
    <element2>5678</element2>
    <element3>bla</element3>
</detailedInformation>

当我编码它时,它应该变成(就像 JAXB java 代码):

<detailedInformation element2="5678" element3="bla">1234</detailedInformation>

因此,我编写了一个 numItemTypeAdapter.class NumItemTypeAdapter 扩展了 XmlAdapter

AdaptedNum.class:

public class AdaptedNum {
    @XmlElement 
    private  double element1;
    @XmlElement
    private String element2;
    @XmlElement
    private String element3;

   /** Some getter/setter methods */
}

我想,这会对我有帮助 http://blog.bdoughan.com/2012/02/xmlanyelement-and-xmladapter.html ,但这有点棘手:-/

最佳答案

准确地找出问题可能发生的位置有点棘手。我假设您的原始模型是从 XML 架构生成的,这应该按原样工作,无需任何修改。我在下面尝试提供您的示例的缩小版本,这可能会有所帮助。

package forum11343610;

import java.util.*;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.*;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Root {

    @XmlElementRef(name = "item", namespace = "xi", type = JAXBElement.class, required = false) 
    protected List<Object> itemList = new ArrayList<Object>();

    public List<Object> getItemList() {
        return itemList;
    }

    public void setItemList(List<Object> itemList) {
        this.itemList = itemList;
    }

}

NumItemType

package forum11343610;

import java.math.BigDecimal;
import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "numItemType", namespace = "xi", propOrder = {
    "num"
})

public class NumItemType {

    @XmlValue
    protected BigDecimal num;
    @XmlAttribute(name = "precision")
    protected String precision;
    @XmlAttribute(name = "decimals")
    protected String decimals;
    //... more Attributes

}

对象工厂

package forum11343610;

import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.*;
import javax.xml.namespace.QName;

@XmlRegistry
public class ObjectFactory {

    private static final QName _detailedInformation_QNAME = new QName("de-schema", "detailedInformation");

    @XmlElementDecl(namespace = "xi", name = "item")
    public JAXBElement<NumItemType> createItem(NumItemType num) {
        return new JAXBElement<NumItemType>(_detailedInformation_QNAME, NumItemType.class, null, num);
    }

    @XmlElementDecl(namespace = "de-schema", name = "detailedInformation", substitutionHeadNamespace = "xi", substitutionHeadName = "item")
    public JAXBElement<NumItemType> createDetailedInformation(NumItemType num) {
        return new JAXBElement<NumItemType>(_detailedInformation_QNAME, NumItemType.class, null, num);
    }

}

演示

package forum11343610;

import java.math.BigDecimal;
import javax.xml.bind.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Root.class, ObjectFactory.class);

        ObjectFactory objectFactory = new ObjectFactory();
        Root root = new Root();

        NumItemType numItemType = new NumItemType();
        numItemType.num = BigDecimal.TEN;
        numItemType.decimals = "1";
        numItemType.precision = "2";
        root.getItemList().add(objectFactory.createDetailedInformation(numItemType));

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(root, System.out);
    }

}

输出

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root xmlns:ns2="de-schema" xmlns:ns3="xi">
    <ns2:detailedInformation precision="2" decimals="1">10</ns2:detailedInformation>
</root>

关于java - JAXB 可映射 XML 元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11343610/

相关文章:

java - Android 错误锁定模式监听器

java - 读取包含多个元素的 XML

xml - 如何在 XML 中定义命名空间?

Apache Camel 中的 JAXB 编码

java - 解码时起始元素丢失

java - Android新手-没有线程的socket客户端

java - 如何使用一个类中的静态变量来更新另一个类中的非静态实例变量?

javascript - JSTree 获取普通 XML 数据

java - JAXB:第三方或外部父类(super class)上的@XmlTransient

java - 如何抑制未检查的类警告