Как сгенерировать Java-аннотированный объект simple-xml из схемы xsd - PullRequest
23 голосов
/ 01 июня 2011

Хорошо, поэтому я искал stackoverflow и нашел оставшиеся без ответа подтемы по этой проблеме, поэтому я хотел бы четко указать на этот вопрос:

Есть ли какой-нибудь инструмент, который будетсгенерировать Simple Xml library * java-класс с примечаниями из схемы xsd?

Я получил пару файлов xsd, описывающих объекты, возвращенные спокойным веб-сервисом, который есть у кого-то ещеразработал и в настоящее время я перевел эти схемы в аннотированные классы simple-xml.Они будут использованы в моем приложении для Android.Было бы лучше просто автоматически синхронизировать любые изменения в схемах и восстановить классы из них.У ребят из ws есть репозиторий совместимых с Джексоном классов для этих схем, однако я не хочу использовать Джексона - я использую Spring Android, поэтому я предпочел бы пойти с предпочтительным simple-xml ,Должно быть что-то, что делает трюк, например, инструмент JAXB xjc.

Если такого инструмента нет - можете ли вы вспомнить какие-либо ловушки при реализации скрипта, генерирующего файл .java для simple-xml из схемы?Может быть, есть какие-то подсказки для инструментов, которые стоит расширить, и для этого нужно просто определить, какие аннотации и когда генерировать?

Заранее - большое спасибо за ваши ответы!

Ответы [ 3 ]

4 голосов
/ 04 июня 2011

Я не верю, что JAXB может использоваться на Android из-за отсутствия требований к пакету ( см. Здесь ), особенно в более ранних версиях API Android. Вместо этого вы можете отправить свой XSD через xjc и получить выходные данные класса JAXB, а затем написать скрипт для преобразования аннотаций JAXB в эквивалентные аннотации Simple XML . Это должно делать именно то, что вы искали.

Однако в идеале, и если бы у вас было время, вы могли бы проверить исходный код для xjc и расширить его, чтобы иметь возможность выводить JAXB или простые аннотированные классы.

4 голосов
/ 23 ноября 2015

Я написал библиотеку для генерации аннотированных Java-классов SimpleXML из XSD.

Вот ссылка: https://github.com/yeshodhan/android-jaxb

Например:

XML-схема

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

    <xsd:element name="Person" type="Person"/>

    <xsd:complexType name="Person">
        <xsd:sequence>
            <xsd:element name="FirstName" type="xsd:string" minOccurs="0" />
            <xsd:element name="LastName" type="xsd:string" minOccurs="0" />
            <xsd:element name="Adult" type="xsd:boolean" minOccurs="0" />
            <xsd:element name="Addresses" type="Addresses" minOccurs="0" />
            <xsd:element name="Gender" type="Gender" minOccurs="0" />
            <xsd:element name="Favorite_Fruits" type="Fruits" minOccurs="0" maxOccurs="3"/>
            <xsd:element name="SomeThing_really_whacky-by-the-user" type="xsd:string" minOccurs="0" />
        </xsd:sequence>
        <xsd:attribute name="id" type="xsd:string"/>
    </xsd:complexType>

    <xsd:complexType name="Addresses">
        <xsd:sequence>
            <xsd:element name="Address" type="Address" minOccurs="0" maxOccurs="unbounded"/>
        </xsd:sequence>
    </xsd:complexType>

    <xsd:complexType name="Address">
        <xsd:sequence>
            <xsd:element name="Line1" type="xsd:string" minOccurs="0" />
            <xsd:element name="Line2" type="xsd:string" minOccurs="0" />
            <xsd:element name="City" type="xsd:string" minOccurs="0" />
            <xsd:element name="State" type="xsd:string" minOccurs="0" />
            <xsd:element name="Country" type="xsd:string" minOccurs="1" />
            <xsd:element name="PostalCode" type="xsd:string" minOccurs="0" />
        </xsd:sequence>
    </xsd:complexType>

    <xsd:simpleType name="Gender">
        <xsd:restriction base="xsd:string">
            <xsd:enumeration value="MALE"/>
            <xsd:enumeration value="FEMALE"/>
            <xsd:enumeration value="NOT_SPECIFIED"/>
        </xsd:restriction>
    </xsd:simpleType>

    <xsd:simpleType name="Fruits">
        <xsd:restriction base="xsd:string">
            <xsd:enumeration value="Apple"/>
            <xsd:enumeration value="Banana"/>
            <xsd:enumeration value="Mango"/>
            <xsd:enumeration value="Orange"/>
            <xsd:enumeration value="Grapes"/>
            <xsd:enumeration value="Watermelon"/>
            <xsd:enumeration value="Peach"/>
            <xsd:enumeration value="Apricot"/>
            <xsd:enumeration value="Grapefruit"/>
        </xsd:restriction>
    </xsd:simpleType>

</xsd:schema>

Созданные классы Java

package com.mickoo.person;

import org.simpleframework.xml.Element;
import org.simpleframework.xml.Namespace;
import org.simpleframework.xml.Root;


@Root(name = "Address")
@Namespace(reference = "http://person.mickoo.com/")
public class Address {

    @Element(name = "Line1", required = false)
    private String line1;
    @Element(name = "Line2", required = false)
    private String line2;
    @Element(name = "City", required = false)
    private String city;
    @Element(name = "State", required = false)
    private String state;
    @Element(name = "Country", required = true)
    private String country;
    @Element(name = "PostalCode", required = false)
    private String postalCode;

    public Address() {
    }

    public String getLine1() {
        return line1;
    }

    public void setLine1(String line1) {
        this.line1 = line1;
    }

    public String getLine2() {
        return line2;
    }

    public void setLine2(String line2) {
        this.line2 = line2;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    public String getPostalCode() {
        return postalCode;
    }

    public void setPostalCode(String postalCode) {
        this.postalCode = postalCode;
    }

}

package com.mickoo.person;

import java.util.List;
import org.simpleframework.xml.ElementList;
import org.simpleframework.xml.Namespace;
import org.simpleframework.xml.Root;


@Root(name = "Addresses")
@Namespace(reference = "http://person.mickoo.com/")
public class Addresses {

    @ElementList(name = "Address", entry = "Address", inline = true, required = false)
    private List<Address> address;

    public Addresses() {
    }

    public List<Address> getAddress() {
        return address;
    }

    public void setAddress(List<Address> address) {
        this.address = address;
    }

}

package com.mickoo.person;

import org.simpleframework.xml.Namespace;
import org.simpleframework.xml.Root;

@Root(name = "Fruits")
@Namespace(reference = "http://person.mickoo.com/")
public enum Fruits {

    Apple,
    Banana,
    Mango,
    Orange,
    Grapes,
    Watermelon,
    Peach,
    Apricot,
    Grapefruit;

}

package com.mickoo.person;

import org.simpleframework.xml.Namespace;
import org.simpleframework.xml.Root;

@Root(name = "Gender")
@Namespace(reference = "http://person.mickoo.com/")
public enum GenderEnum {

    MALE(0, "Men are from Mars"),
    FEMALE(1, "Women are from Venus"),
    NOT_SPECIFIED(2, "Can't say anything");
    private final Integer id;
    private final String description;

    private GenderEnum(Integer id, String description) {
        this.id = id;
        this.description = description;
    }

    public Integer id() {
        return id;
    }

    public String description() {
        return description;
    }

}


package com.mickoo.person;

import java.util.List;
import org.simpleframework.xml.Attribute;
import org.simpleframework.xml.Element;
import org.simpleframework.xml.ElementList;
import org.simpleframework.xml.Namespace;
import org.simpleframework.xml.Root;


@Root(name = "Person")
@Namespace(reference = "http://person.mickoo.com/")
public class Person {

    @Element(name = "FirstName", required = false)
    private String firstName;
    @Element(name = "LastName", required = false)
    private String lastName;
    @Element(name = "Adult", required = false)
    private Boolean adult;
    @Element(name = "Addresses", required = false)
    private Addresses addresses;
    @Element(name = "Gender", required = false)
    private GenderEnum gender;
    @ElementList(name = "Favorite_Fruits", entry = "Favorite_Fruits", inline = true, required = false)
    private List<Fruits> favoriteFruits;
    @Element(name = "SomeThing_really_whacky-by-the-user", required = false)
    private String someThingReallyWhackyByTheUser;
    @Attribute(name = "id", required = false)
    private String id;

    public Person() {
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public Boolean getAdult() {
        return adult;
    }

    public void setAdult(Boolean adult) {
        this.adult = adult;
    }

    public Addresses getAddresses() {
        return addresses;
    }

    public void setAddresses(Addresses addresses) {
        this.addresses = addresses;
    }

    public GenderEnum getGender() {
        return gender;
    }

    public void setGender(GenderEnum gender) {
        this.gender = gender;
    }

    public List<Fruits> getFavoriteFruits() {
        return favoriteFruits;
    }

    public void setFavoriteFruits(List<Fruits> favoriteFruits) {
        this.favoriteFruits = favoriteFruits;
    }

    public String getSomeThingReallyWhackyByTheUser() {
        return someThingReallyWhackyByTheUser;
    }

    public void setSomeThingReallyWhackyByTheUser(String someThingReallyWhackyByTheUser) {
        this.someThingReallyWhackyByTheUser = someThingReallyWhackyByTheUser;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

}

Использование

➜  target git:(master) ✗ java -jar android-jaxb-1.0.jar --help
usage: java -jar android-jaxb-1.0.jar [options] your-schema-file.xsd
---------------------------------------------------------------------
 -b,--bindings <arg>      (optional) bindings JSON file
 -d,--destination <arg>   destination directory for generated classes
 -h,--help                Help on usage
 -p,--package <arg>       package name for generated classes. Eg.:
                          com.example.app
 -v,--version             Version
---------------------------------------------------------------------
0 голосов
/ 01 июня 2011

Насколько я знаю, Simple XML используется для создания аннотированных классов для Marshall / Demarshall XML.
Платформы веб-служб Java, используйте определенные привязки:
Например. CXF поддерживает (кроме JAXB) Aegis, XML Beans и т. Д. Привязки данных CXF
Axis2 поддерживает ADB, XMLBeans и т. Д. Связывания данных Axis2
То же самое для JAX-WS
Я не знаю о Spring WS (но сомневаюсь, что они поддерживают конкретно простую)
ИМХО, если вам абсолютно необходимо использовать Simple XML, просто создайте классы самостоятельно. Это кажется возможным в вашем случае, так как вы заметили:

I received a couple of xsd files describing the objects returned by a restful web-service 

Так что для нескольких файлов это возможно. Я не думаю, что вам следует беспокоиться об изменениях в схеме со стороны разработчиков веб-служб, поскольку, если они внесут изменения, вам все равно придется заново генерировать свою клиентскую часть. В любом случае после развертывания веб-службы схемы не изменяются, что часто влияет на все клиентские приложения.
Если вы хотите создать свой собственный инструмент, вам нужно будет создать генератор кода, который будет анализировать файлы xsd и создавать аннотированные классы для Simple XML. Это кажется мне большим усилием
Надеюсь, это поможет

...