**XSD1**
<xs:complexType name="Root1">
<xs:sequence>
<xs:element name="Revision" type="xs:string" />
<xs:element name="Header" type="Header" />
<xs:element name="Body" type="SwAny" minOccurs="0" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="SwAny" mixed="true">
<xs:sequence>
<xs:any namespace="##any" processContents="skip" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
The JAVA Object for the above XSD is like below
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "root1", propOrder = {
"revision",
"header",
"body"
})
public class Root1
implements Serializable
{
private final static long serialVersionUID = 1L;
@XmlElement(name = "Revision", required = true)
protected String revision;
@XmlElement(name = "Header", required = true)
protected SAA_Header header;
@XmlElement(name = "Body")
protected SAA_SwAny body;
-- getter and setter --
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "SwAny", propOrder = {
"content"
})
public class SAA_SwAny
implements Serializable
{
private final static long serialVersionUID = 1L;
@XmlMixed
@XmlAnyElement
protected List<Object> content;
}
I have another XSD which I have marshalled and generated POJO objects like below
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Header", propOrder = {
"fr",
"to"
})
public class Header
implements Serializable
{
private final static long serialVersionUID = 1L;
@XmlElement(name = "Fr", required = true)
protected PartyChoice__1 fr;
@XmlElement(name = "To", required = true)
protected PartyChoice__1 to;
-- getter & setter --
}
In my class where I marshall, I create like below and marshall
Header header = new Header();
header.setFr(fr);
header.setTo(to);
Root1 **pdu** = new Root1();
**pdu**.setRevision("rev");
SAA_SwAny any = new SAA_SwAny();
any.getContent().add(header);
Marshaller mars = cfgsvc.createMarshaller(jaxbCtx, true, "UTF8", false, localPart);
String schemaLoc = cfgsvc.findSchemaLoc(localPart);
JAXBElement<?> elm = new JAXBElement(xmlQName, docCls, **pdu**);
sw = new StringWriter();
mars.marshal(elm, sw);`
按照上面的代码执行时,遇到下面的异常
原因:com.sun.istack.SAXException2:无法将类型“com.test.Header”封送为元素,因为它缺少 @XmlRootElement 注释 在 com.sun.xml.bind.v2.runtime.XMLSerializer.reportError(XMLSerializer.java:225) ~[jaxb-impl-2.0.1.jar:2.0.1] 在 com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeRoot(ClassBeanInfoImpl.java:274) ~[jaxb-impl-2.0.1.jar:2.0.1] 在 com.sun.xml.bind.v2.runtime.property.ArrayReferenceNodeProperty.serializeListBody(ArrayReferenceNodeProperty.java:78) ~[jaxb-impl-2.0.1.jar:2.0.1] 在 com.sun.xml.bind.v2.runtime.property.ArrayERProperty.serializeBody(ArrayERProperty.java:101) ~[jaxb-impl-2.0.1.jar:2.0.1] 在 com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:293) ~[jaxb-impl-2.0.1.jar:2.0.1] 在 com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:619) ~[jaxb-impl-2.0.1.jar:2.0.1] 在 com.sun.xml.bind.v2.runtime.property.SingleElementNodeProperty.serializeBody(SingleElementNodeProperty.java:114) ~[jaxb-impl-2.0.1.jar:2.0.1] 在 com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:293) ~[jaxb-impl-2.0.1.jar:2.0.1] 在 com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:619) ~[jaxb-impl-2.0.1.jar:2.0.1] 在 com.sun.xml.bind.v2.runtime.property.SingleElementNodeProperty.serializeBody(SingleElementNodeProperty.java:114) ~[jaxb-impl-2.0.1.jar:2.0.1] 在 com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl$1.serializeBody(ElementBeanInfoImpl.java:98) ~[jaxb-impl-2.0.1.jar:2.0.1] 在 com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl$1.serializeBody(ElementBeanInfoImpl.java:127) ~[jaxb-impl-2.0.1.jar:2.0.1] 在 com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl.serializeBody(ElementBeanInfoImpl.java:244) ~[jaxb-impl-2.0.1.jar:2.0.1] 在 com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl.serializeRoot(ElementBeanInfoImpl.java:251) ~[jaxb-impl-2.0.1.jar:2.0.1] 在 com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl.serializeRoot(ElementBeanInfoImpl.java:33) ~[jaxb-impl-2.0.1.jar:2.0.1] 在 com.sun.xml.bind.v2.runtime.XMLSerializer.childAsRoot(XMLSerializer.java:461) ~[jaxb-impl-2.0.1.jar:2.0.1] 在 com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:292) ~[jaxb-impl-2.0.1.jar:2.0.1]
The workaround i did was in the header class added the below code
**@XmlRootElement(name = "header", namespace = "head.namespace")**
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Header", propOrder = {
"fr",
"to"
})
public class Header
implements Serializable
{
private final static long serialVersionUID = 1L;
@XmlElement(name = "Fr", required = true)
protected PartyChoice__1 fr;
@XmlElement(name = "To", required = true)
protected PartyChoice__1 to;
-- getter & setter --
}
now the xml marshaller works as expected and i get the below xml
<?xml version="1.0" encoding="UTF8" standalone="yes"?>
<PDU xsi:schemaLocation="...." xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Revision>rev</Revision>
<Body>
<head:Hdr>
<head:Fr>
<head:Id>
<head:InstnId>
<head:FI>AAAASGSGXXX</head:FI>
</head:InstnId>
</head:Id>
</head:Fr>
<head:To>
<head:Id>
<head:InstnId>
<head:FI>AAAASGSGXXX</head:FI>
</head:InstnId>`your text`
</head:Id>
</head:To>
</head:Hdr>
</Body>
</PDU>
我期待一个无需手动添加 @xmlrootelement 的解决方案。 JAXB 有办法解决这个问题吗?
假设您正在使用像以前的 maven-jaxb2-plugin 这样的工具,并使用 jaxb api 3+ (雅加达版本),您可以使用以下绑定文件告诉 xjc 在生成的每个类上添加
@XmlRootElement
(有趣的是部分是<xjc:simple/>
)
<?xml version="1.0" encoding="UTF-8"?>
<jxb:bindings
xmlns:jxb="https://jakarta.ee/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
jxb:extensionBindingPrefixes="xjc"
jxb:version="3.0">
<jxb:globalBindings>
<xjc:simple/>
</jxb:globalBindings>
</jxb:bindings>
希望对你有帮助。
我说的是以前的maven-jaxb2-plugin,因为该插件在最新版本中被重命名(查看迁移指南)