You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用JAXB创建Cell类映射XML元素、属性或仅文本值?

解决JAXB中Cell类支持两种XML结构的问题

嘿,这个JAXB的问题我刚好碰到过,给你捋捋怎么解决!首先得说清楚为啥你之前的写法不行:JAXB确实不允许在同一个类里同时用@XmlValue和@XmlElement(除非用@XmlMixed处理混合内容,但你之前没配置对)。要实现你要的两种<cell>标签结构,正确的做法是用@XmlMixed结合@XmlElement定义混合内容,同时保留@XmlAttribute处理display属性。

正确的Cell类实现

import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.*;
import javax.xml.namespace.QName;
import java.util.List;

public class Cell {
    private String display;
    private List<Object> content;

    @XmlAttribute
    public String getDisplay() {
        return display;
    }

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

    @XmlMixed
    @XmlElement(name = "text", type = String.class)
    public List<Object> getContent() {
        return content;
    }

    public void setContent(List<Object> content) {
        this.content = content;
    }

    // 工具方法:快速创建带<text>子元素的Cell
    public static Cell withTextElement(String textContent, String display) {
        Cell cell = new Cell();
        cell.setDisplay(display);
        JAXBElement<String> textElement = new JAXBElement<>(
                new QName("text"),
                String.class,
                textContent
        );
        cell.setContent(List.of(textElement));
        return cell;
    }

    // 工具方法:快速创建带纯文本内容的Cell
    public static Cell withPlainText(String plainText) {
        return withPlainText(plainText, null);
    }

    public static Cell withPlainText(String plainText, String display) {
        Cell cell = new Cell();
        cell.setDisplay(display);
        cell.setContent(List.of(plainText));
        return cell;
    }
}

配套的Page类

因为你的Cell标签是作为Page的子元素列表存在的,所以Page类要这么写:

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.List;

@XmlRootElement(name = "Page")
public class Page {
    private List<Cell> cells;

    @XmlElement(name = "cell")
    public List<Cell> getCells() {
        return cells;
    }

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

代码解释

  • @XmlMixed:这个注解告诉JAXB,当前类的内容可以是纯文本和子元素的混合,完美适配你需要的两种<cell>结构。
  • @XmlElement(name = "text"):指定子元素名称为<text>,当content列表里放JAXBElement<String>对象时,JAXB会生成<text>...</text>子元素;如果放普通String,就直接生成纯文本内容。
  • @XmlAttribute:用来映射display属性,两种<cell>结构都可以带这个属性(不带的话设为null即可)。

测试生成XML

用下面的代码可以生成你给出的示例XML结构:

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import java.util.List;

public class Main {
    public static void main(String[] args) throws Exception {
        JAXBContext context = JAXBContext.newInstance(Page.class);
        Marshaller marshaller = context.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

        Page page = new Page();
        page.setCells(List.of(
                Cell.withTextElement("thisIsText1", "a"),
                Cell.withTextElement("thisIsText2", "b"),
                Cell.withTextElement("thisIsText3", "c"),
                Cell.withPlainText("value1"),
                Cell.withPlainText("value2"),
                Cell.withPlainText("value3")
        ));

        marshaller.marshal(page, System.out);
    }
}

运行后输出的XML就是你要的:

<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>

解析时的处理

如果要解析这种XML,拿到Cell对象后,可以通过判断content列表里的元素类型区分纯文本和<text>子元素:

for (Object item : cell.getContent()) {
    if (item instanceof String) {
        // 纯文本内容
        String plainText = (String) item;
        System.out.println("Plain text: " + plainText);
    } else if (item instanceof JAXBElement) {
        // <text>子元素的内容
        JAXBElement<String> textElement = (JAXBElement<String>) item;
        System.out.println("Text element content: " + textElement.getValue());
    }
}

内容的提问来源于stack exchange,提问作者JoeWill

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:31:49