1

我从一些第三方那里得到了一个 xsd 文件,这些文件曾经是“包含”而不是“导入”。我正在使用这些 xsd 文件生成 java 文件,使用 jaxb。最初的 xsd 结构导致输出相同的类包含在不同的包中。例如,如果生成了两个包“aa”和“bb”,它们都包含相同的公共文件:

aa/commonElement.java
aa/a.java

bb/commonElement.java
bb/b.java

这是我想避免的事情,我希望 commonElement.java 在单个包中创建一次,而不是由其余包导入,因此我开始使用 import 代替。

<xs:schema xmlns="http://www.ns.com/aa" xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:DD="http://www.ns.com/common" targetNamespace="http://www.ns.com/aa" elementFormDefault="qualified" jaxb:version="1.0" jaxb:extensionBindingPrefixes="xjc">

 <xs:import namespace="http://www.ns.com/common"  schemaLocation="common.xsd"/>
   <xs:element name="Response">
                <xs:complexType>
                        <xs:sequence>
                                    <xs:element name="element" type="DD:commonElement" ../>

正如我所料,创建和编译了 java 类。

common/commonElement.java
aa/aa.java

问题是当我从 api 调用接收到 aa 的结果并解组结果时,我得到了一个带有正确创建的 commonElement 的类,但带有空字段。

我的猜测是这些字段是空的,因为 unmarshler 不明白他需要在“common”命名空间中查找定义,而是在“aa”命名空间中查找它们,但如何使其正常工作?

谢谢您的帮助

4

2 回答 2

0

我没有足够的信息来诊断为什么你的解组没有正确发生。以下将起作用,您可以将其与您正在做的事情进行比较以查找错误。

最有可能的候选人是:

  • 创建 JAXBContext 时,您没有告诉 JAXB 足够多的类。
  • 您的 XML 文档没有正确的命名空间限定。

使用以下模式:

常见的.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    targetNamespace="http://www.ns.com/common" 
    xmlns="http://www.ns.com/common" 
    elementFormDefault="qualified">

    <xs:complexType name="commonElement">
        <xs:sequence>
            <xs:element name="commonChild" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>
</xs:schema>

aa.xsd

<xs:schema xmlns="http://www.ns.com/aa" xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:DD="http://www.ns.com/common" targetNamespace="http://www.ns.com/aa"
    elementFormDefault="qualified">

    <xs:import namespace="http://www.ns.com/common"
        schemaLocation="common.xsd" />

    <xs:element name="Response">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="element" type="DD:commonElement" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

生成了以下类:

com.ns.aa.package-info

@javax.xml.bind.annotation.XmlSchema(namespace = "http://www.ns.com/aa", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package com.ns.aa;

com.ns.aa.Response

package com.ns.aa;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import com.ns.common.CommonElement;

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

    @XmlElement(required = true)
    protected CommonElement element;

    public CommonElement getElement() {
        return element;
    }

    public void setElement(CommonElement value) {
        this.element = value;
    }

}

com.ns.common.package-info

@javax.xml.bind.annotation.XmlSchema(namespace = "http://www.ns.com/common", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package com.ns.common;

com.ns.common.CommonElement

package com.ns.common;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "commonElement", propOrder = {
    "commonChild"
})
public class CommonElement {

    @XmlElement(required = true)
    protected String commonChild;

    public String getCommonChild() {
        return commonChild;
    }

    public void setCommonChild(String value) {
        this.commonChild = value;
    }

}

使用这些类,我可以解组以下 XML 文档:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:Response xmlns="http://www.ns.com/common" xmlns:ns2="http://www.ns.com/aa">
    <ns2:element>
        <commonChild>FOO</commonChild>
    </ns2:element>
</ns2:Response>

使用以下代码:

演示

import java.io.File;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

import com.ns.aa.Response;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Response.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("input.xml");
        Response response = (Response) unmarshaller.unmarshal(xml);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(response, System.out);
    }
}
于 2010-09-01T20:52:30.193 回答
0

我有一个问题,如果知道,请解释一下。我已经尝试了上面的答案,并且在给定的细节下它工作正常。

但是假设我想在下面进行 xml 验证它会和你给出的一样,但是我做了一些我想验证的小改动

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Response xmlns="http://www.ns.com/aa">
    <element xmlns="http://www.ns.com/common">
        <commonChild>FOO</commonChild>
    </element>
</Response>

但它会给出以下错误

SAX Exception: cvc-complex-type.2.4.a: Invalid content was found starting with element 'element'. One of '{"http://www.ns.com/aa":element}' is expected.
 is not valid against 
于 2020-03-26T08:26:12.197 回答