使用JaXB

时间:2017-10-27 11:28:53

标签: jaxb attributes

我正在尝试简化POJO到XML的转换,但我遇到了类字段属性的问题。

考虑以下XML文件

 <cat>
        <displayTexts>
            <displayText language="en">12</displayText>
            <displayText language="en">23</displayText>
        </displayTexts>
    </cat>   

并且

我有一个班级

@XmlRootElement(name = "cat")
public class Category{
    List<Integer> list;

    public List<Integer> getList() {
        return list;
    }

    @XmlElementWrapper(name = "displayTexts")
    @XmlElement(name = "displayText")
    public void setList(List<Integer> list) {
        this.list = list;
    }


}

如何编写一个能够生成上述XML的适配器?

现在它将生成类似于xml ::

的内容
<cat>
        <displayTexts>
            <displayText>12</displayText>
            <displayText>23</displayText>
        </displayTexts>
    </cat>

注意:: 我不允许使用MoXy。我知道我可以通过写一个不同的课来实现这一目标。问题是我们可以编写一个适配器,以便我可以为任何类字段推广这个属性吗?

1 个答案:

答案 0 :(得分:0)

虽然我仍然建议使用class而不是Integer来使用displayText的值及其属性,但是如果你想在没有任何新类的情况下实现,你可以使用@XmlAnyElement为你的displayList和“自己创建”xml:

import java.util.Arrays;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.XmlAnyElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

@XmlRootElement(name = "cat")
public class Category {

    List<Integer> list;

    @XmlAnyElement()
    @XmlJavaTypeAdapter(MyIntegerAdapter.class)
    public List<Integer> getList() {
        return list;
    }
    //@XmlElement(name = "displayText")

    public void setList(List<Integer> list) {
        this.list = list;
    }

    public static void main(String[] args) throws Exception {
        Category bx = new Category();

        List<Integer> lists = Arrays.asList(121, 212);
        bx.setList(lists);

        JAXBContext jc = JAXBContext.newInstance(Category.class);
        MyIntegerAdapter adapter = new MyIntegerAdapter();
        Marshaller marrshaller = jc.createMarshaller();
        marrshaller.setAdapter(adapter);
        marrshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);

        marrshaller.marshal(bx, System.out);
    }
}

class MyIntegerAdapter extends XmlAdapter<Element, List<Integer>> {

    private DocumentBuilder documentBuilder;

    public MyIntegerAdapter() {
    }

    private DocumentBuilder getDocumentBuilder() throws Exception {
        // Lazy load the DocumentBuilder as it is not used for unmarshalling.
        if (null == documentBuilder) {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            documentBuilder = dbf.newDocumentBuilder();
        }
        return documentBuilder;
    }

    @Override
    public Element marshal(List<Integer> lists) throws Exception {
        if (null == lists) {
            return null;
        }
        Document document = getDocumentBuilder().newDocument();
        Element element = document.createElement("displayTexts");
        for (int value : lists) {
            Element displayText = document.createElement("displayText");
            System.out.println("value.." + value);
            displayText.setTextContent(value + "");
            displayText.setAttribute("Lang", "en");
            element.appendChild(displayText);
        }
        return element;
    }

    @Override
    public List<Integer> unmarshal(Element v) throws Exception {
        //TODO
        throw new UnsupportedOperationException(); 

    }
}