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

扩展瞬态类时如何移除XML中的xs:type标签?

问题:如何移除XML中child标签的xs:type属性?

预期结果

能够在以下两种XML结构间切换:

<root>
  <child>
    <prop1>..</prop1>
    <prop2>..</prop2>
  </child>
</root>

和

<root>
  <child>
    <prop1>..</prop1>
    <prop2>..</prop2>
    <prop3>..</prop3>
    <prop4>..</prop4>
  </child>
</root>

我的代码

Root.java

@XmlRootElement(name= "root")
public class Root {
  @XmlElement(name="child")
  public Child child;
}

ExtendedRoot.java

@XmlRootElement(name= "root")
public class ExtendedRoot extends Root {
  @XmlElement(name="child")
  public ExtendedChild child;
}

Child.java

@XmlTransient
public class Child {
  // prop1, prop2
}

ExtendedChild.java

@XmlType(propOrder = {"prop1", "prop3","prop4", "prop2"})
public class ExtendedChild extends Child {
  // prop3, prop4
}

主程序代码

System.setProperty("javax.xml.bind.context.factory", "org.eclipse.persistence.jaxb.JAXBContextFactory");
Class clazz = extendChild ? ExtendedRoot.class : Root.class;
JAXBContext jc = JAXBContext.newInstance(clazz);
Marshaller marshaller = jc.createMarshaller();
marshaller.marshal(formattedJob, tempFile);

实际结果

<root>
  <child xs:type="ExtendedChild">
    <prop1>..</prop1>
    <prop2>..</prop2>
    <prop3>..</prop3>
    <prop4>..</prop4>
  </child>
</root>

解决方案

xs:type是JAXB处理多态类型时默认添加的标识,要移除它可以用以下几种方法:

方法1:修改ExtendedRoot的字段注解

在ExtendedRoot类的child字段的@XmlElement注解中指定type = Object.class,让JAXB不识别该字段的多态特性:

@XmlRootElement(name= "root")
public class ExtendedRoot extends Root {
  @XmlElement(name="child", type = Object.class)
  public ExtendedChild child;
}

方法2:使用MOXy特有的Marshaller属性

因为你用的是EclipseLink MOXy作为JAXB实现,可以通过设置Marshaller属性禁用类型属性输出:

import org.eclipse.persistence.jaxb.MarshallerProperties;

// ...
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(MarshallerProperties.XML_TYPE_ATTRIBUTE, false); // 禁用xs:type输出
marshaller.marshal(formattedJob, tempFile);

方法3:调整实体类的Xml注解

  1. 移除Child类上的@XmlTransient注解,让JAXB可以识别该基类:
public class Child {
  // prop1, prop2
}
  1. 在ExtendedChild类的@XmlType中指定name = "child",让JAXB将其视为与基类同名的类型:
@XmlType(name = "child", propOrder = {"prop1", "prop3","prop4", "prop2"})
public class ExtendedChild extends Child {
  // prop3, prop4
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 10:09:56