Генерация классов Java из файлов XSD - PullRequest
1 голос
/ 31 августа 2010

У меня есть файлы xsd от какого-то третьего участника, который имел обыкновение использовать «include», а не «import». Я использую эти xsd-файлы для создания java-файлов, используя jaxb. Исходная структура xsd привела к выводу, в котором один и тот же класс был включен в разные пакеты. например, если были сгенерированы два пакета, «aa» и «bb», оба включали один и тот же общий файл:

аа / commonElement.java
аа / a.java

бб / commonElement.java
бб / b.java

Это было то, чего я хотел избежать, я хотел, чтобы commonElement.java создавался один раз в одном пакете, а затем импортировался остальными, поэтому вместо этого я начал использовать импорт.

<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-классы были созданы и скомпилированы, как я и ожидал.

общая / commonElement.java
аа / aa.java

Проблема в том, что когда я получаю результат aa из вызова API и отменяю маршализацию результатов, я получаю класс с CommonElement, созданным правильно, но с пустыми полями.

Я предполагаю, что поля пусты, потому что демон не понимает, что ему нужно искать определение в «общем» пространстве имен, а вместо этого ищет их в «aa» именном пространстве, но как заставить его работать правильно?

Спасибо за помощь

1 Ответ

0 голосов
/ 02 сентября 2010

У меня недостаточно информации, чтобы диагностировать, почему ваш маршал не происходит правильно.Следующее сработает, вы можете сравнить его с тем, что вы делаете, чтобы найти ошибку.

Наиболее вероятные кандидаты:

  • Вы недостаточно рассказываете JAXBклассы при создании JAXBContext.
  • Ваш XML-документ неправильно определен для пространства имен.

Использование следующих схем:

common.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);
    }
}
...