使用JAXB,如何创建一个类对象来映射元素,属性OR只有值?

时间:2018-01-30 14:58:13

标签: java xml jaxb

我需要一个类对象" Cell"可用于创建以下标记:

<cell display="orange"><text>Performances</text></cell>

但也是:

<cell>SomethingWritten</cell>

据我所知,我需要使用Xmlattribute(显示),Xmlelement(文本)以及Xmlvalue创建一个类。 所以看起来像这样:

public class Cell {

private String text;

@XmlAttribute
private String display;

@XmlValue
private String value;
}

由于元素和价值的使用是(似乎是)禁止的,它怎么可能?值得注意的是,Cell标签始终用作父标签中的对象列表。所以我总是有类似的东西:

<Page>
   <cell display="a"><text>thisIsText1</text></cell>
   <cell display="b"><text>thisIsText2</text></cell>
   <cell display="c"><text>thisIsText3</text></cell>
   <cell>value1</cell>
   <cell>value2</cell>
   <cell>value3</cell>
<Page/>

我尝试使用XmlMixed但从未成功。 提前谢谢。

1 个答案:

答案 0 :(得分:1)

下面的代码是糟糕的设计,可能无法在XML到Java方向上运行良好,但它确实解决了一个核心问题,即XML元素不能同时具有值​​和子元素。

我确信XML是以这种方式编写的一个很好的理由,因此在这里创建的文档结构可能会破坏他们的一些设计原则,这里是如何做到的:

@XmlRootElement(name="page")
@XmlAccessorType(XmlAccessType.NONE)
public class Page {
    @XmlElements ( value = {
            @XmlElement(name = "cell", type = Cell.class),
            @XmlElement(name = "cell", type = CellValue.class)
        }
    )
    public List getValues()
    {
        List values = new ArrayList();
        values.addAll(cells);
        values.addAll(cellValues);
        return values;
    }

    private List<Cell> cells;
    private List<CellValue> cellValues;

    public Page(){
        cells= new ArrayList<>();
        cellValues = new ArrayList<>();
    }

    public List<Cell> getCells() {
        return cells;
    }

    public void setCells(List<Cell> cells) {
        this.cells = cells;
    }

    public List<CellValue> getCellValues() {
        return cellValues;
    }

    public void setCellValues(List<CellValue> cellValues) {
        this.cellValues = cellValues;
    }
}

@XmlRootElement(name = "cell")
@XmlAccessorType(XmlAccessType.NONE)
public class Cell {

    @XmlElement
    private Text text;
    @XmlAttribute
    private String display;

    public Cell() {
    }

    public Text getText() {
        return text;
    }

    public void setText(Text text) {
        this.text = text;
    }

    public String getDisplay() {
        return display;
    }

    public void setDisplay(String display) {
        this.display = display;
    }
}

@XmlRootElement(name = "text")
@XmlAccessorType(XmlAccessType.NONE)
public class Text {

    @XmlValue
    private String text;

    public Text(){}

    public Text(String text){
        this.text = text;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }
}

@XmlRootElement(name = "cell")
@XmlAccessorType(XmlAccessType.NONE)
public class CellValue {

    @XmlValue
    private String value;

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}

使用示例:

    Cell c1 = new Cell();
    c1.setDisplay("123");
    c1.setText(new Text("abc"));

    Cell c2 = new Cell();
    c2.setDisplay("456");
    c2.setText(new Text("def"));

    Page page = new Page();
    page.getCells().add(c1);
    page.getCells().add(c2);

    CellValue cv1 = new CellValue();
    cv1.setValue("value1");

    CellValue cv2 = new CellValue();
    cv2.setValue("value2");

    page.getCellValues().add(cv1);
    page.getCellValues().add(cv2);

    JAXBContext jc = JAXBContext.newInstance(Page.class);

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

输出:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<page>
    <cell display="123">
        <text>abc</text>
    </cell>
    <cell display="456">
        <text>def</text>
    </cell>
    <cell>value1</cell>
    <cell>value2</cell>
</page>