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

XJC无法正确生成混合元素类,寻求技术解决方案

解决xjc从DTD生成混合内容类时忽略子元素的问题

问题原因

xjc(JAXB 2.3.1)处理DTD中的混合内容定义<!ELEMENT Description ( #PCDATA | ShortName )* >时,默认会将其解析为纯文本内容,只生成带@XmlValue注解的String属性,忽略了ShortName子元素的结构,导致无法生成包含文本和子元素的目标XML。

解决方案

有两种可行的处理方式:

1. 手动修改生成的Description类

直接调整生成的Description类,替换原有的value属性为支持混合内容的列表结构:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = { "content" })
@XmlRootElement(name = "Description")
public class Description {

    @XmlAttribute(name = "xml:lang", required = true)
    @XmlJavaTypeAdapter(NormalizedStringAdapter.class)
    protected String xmlLang;

    @XmlMixed
    @XmlElementRef(name = "ShortName", type = ShortName.class, required = false)
    protected List<Object> content;

    // 生成getter和setter方法
    public String getXmlLang() {
        return xmlLang;
    }

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

    public List<Object> getContent() {
        if (content == null) {
            content = new ArrayList<Object>();
        }
        return this.content;
    }
}

这样content列表中可以同时存放文本字符串和ShortName对象,序列化时就能生成目标XML结构。

2. 通过绑定文件让xjc自动生成正确结构

创建绑定文件binding.xjb,指定xjc对Description元素的混合内容处理规则:

<jaxb:bindings version="2.3" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
               xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
               jaxb:extensionBindingPrefixes="xjc">
    <jaxb:bindings schemaLocation="your.dtd" node="/">
        <jaxb:bindings node="//ELEMENT[@name='Description']">
            <jaxb:property>
                <jaxb:baseType name="java.util.List"/>
                <jaxb:mixed/>
            </jaxb:property>
        </jaxb:bindings>
    </jaxb:bindings>
</jaxb:bindings>

然后在Maven的xjc插件配置中引入该绑定文件:

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>jaxb2-maven-plugin</artifactId>
    <version>2.5.0</version>
    <executions>
        <execution>
            <goals>
                <goal>xjc</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <schemaFiles>your.dtd</schemaFiles>
        <bindingFiles>binding.xjb</bindingFiles>
        <extension>true</extension>
    </configuration>
</plugin>

重新执行Maven构建,xjc就会自动生成包含混合内容列表的Description类,无需手动修改。

使用示例

构建目标XML时,只需向content列表中添加文本和ShortName对象即可:

Description desc = new Description();
desc.setXmlLang("pt_BR");
List<Object> content = desc.getContent();
content.add("a large ball made of leather or plastic and filled with air, used in games of soccer");
ShortName shortName = new ShortName();
shortName.setValue("Soccer ball");
content.add(shortName);

// 序列化XML
JAXBContext context = JAXBContext.newInstance(Description.class);
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(desc, System.out);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 22:25:17