无法使用 JAXB 编组器为来自不同包的嵌套对象生成 XML

问题描述 投票:0回答:1
**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 有办法解决这个问题吗?

xsd jaxb marshalling maven-jaxb2-plugin
1个回答
0
投票

假设您正在使用像以前的 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,因为该插件在最新版本中被重命名(查看迁移指南

© www.soinside.com 2019 - 2024. All rights reserved.