Java-код в XML / XSD без использования аннотации

Мне нужно Маршалл и unmarshall класс Java в XML. Класс в не принадлежащей мне, что я не могу добавить anotations, так что я могу использовать JAXB.

есть ли хороший способ преобразовать Java в XML с данным contraint?

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

4 ответов


Примечание: я EclipseLink JAXB (MOXy) ведущий и член JAXB (JSR-222) группы экспертов.

МОДЕЛЬ ДОМЕНА

я буду использовать следующую модель домена для данного ответа. Обратите внимание, как нет аннотаций JAXB на модель.

клиент

package forum11693552;

import java.util.*;

public class Customer {

    private String firstName;
    private String lastName;
    private List<PhoneNumber> phoneNumbers = new ArrayList<PhoneNumber>();

    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 List<PhoneNumber> getPhoneNumbers() {
        return phoneNumbers;
    }

    public void setPhoneNumbers(List<PhoneNumber> phoneNumbers) {
        this.phoneNumbers = phoneNumbers;
    }

}

номер телефона

package forum11693552;

public class PhoneNumber {

    private String type;
    private String number;

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }

}

Вариант #1-любая реализация JAXB (JSR-222)

JAXB является configurartion исключения, это означает, что вам нужно только добавить аннотации, где требуется сопоставление поведения отличаются от дефолта. Ниже приведена ссылка на пример, демонстрирующий, как использовать любой JAXB impl без Примечания:

демо

package forum11693552;

import javax.xml.bind.*;
import javax.xml.namespace.QName;

public class Demo {

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

        Customer customer = new Customer();
        customer.setFirstName("Jane");
        customer.setLastName("Doe");

        PhoneNumber workPhone = new PhoneNumber();
        workPhone.setType("work");
        workPhone.setNumber("555-1111");
        customer.getPhoneNumbers().add(workPhone);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        JAXBElement<Customer> rootElement = new JAXBElement<Customer>(new QName("customer"), Customer.class, customer);
        marshaller.marshal(rootElement, System.out);
    }

}

выход

<customer>
    <firstName>Jane</firstName>
    <lastName>Doe</lastName>
    <phoneNumbers>
        <number>555-1111</number>
        <type>work</type>
    </phoneNumbers>
</customer>

Для Получения Дополнительной Информации


опция #2-документ внешнего отображения EclipseLink JAXB (MOXy)

если вы если вы хотите настроить сопоставления, вас может заинтересовать расширение внешнего документа сопоставления MOXy. Пример документа сопоставления выглядит следующим образом:

oxm.в XML

<?xml version="1.0"?>
<xml-bindings xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
    package-name="forum11693552">
    <java-types>
        <java-type name="Customer">
            <xml-root-element />
            <java-attributes>
                <xml-element java-attribute="firstName" name="first-name" />
                <xml-element java-attribute="lastName" name="last-name" />
                <xml-element java-attribute="phoneNumbers" name="phone-number" />
            </java-attributes>
        </java-type>
        <java-type name="PhoneNumber">
            <java-attributes>
                <xml-attribute java-attribute="type" />
                <xml-value java-attribute="number" />
            </java-attributes>
        </java-type>
    </java-types>
</xml-bindings>

в JAXB.свойства

чтобы включить MOXy в качестве поставщика JAXB, вам нужно включить файл с именем jaxb.properties в том же пакете, что и ваша модель домена со следующей записью (см.: http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html):

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

демо

при использовании EclipseLink MOXy в качестве поставщика JAXB (см.) Вы можете использовать внешний документ сопоставления при загрузке JAXBContext

package forum11693552;

import java.util.*;
import javax.xml.bind.*;
import javax.xml.namespace.QName;
import org.eclipse.persistence.jaxb.JAXBContextFactory;

public class Demo {

    public static void main(String[] args) throws Exception {
        Map<String, Object> properties = new HashMap<String,Object>(1);
        properties.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, "forum11693552/oxm.xml");
        JAXBContext jc = JAXBContext.newInstance(new Class[] {Customer.class}, properties);

        Customer customer = new Customer();
        customer.setFirstName("Jane");
        customer.setLastName("Doe");

        PhoneNumber workPhone = new PhoneNumber();
        workPhone.setType("work");
        workPhone.setNumber("555-1111");
        customer.getPhoneNumbers().add(workPhone);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        JAXBElement<Customer> rootElement = new JAXBElement<Customer>(new QName("customer"), Customer.class, customer);
        marshaller.marshal(rootElement, System.out);
    }

}

выход

<?xml version="1.0" encoding="UTF-8"?>
<customer>
   <first-name>Jane</first-name>
   <last-name>Doe</last-name>
   <phone-number type="work">555-1111</phone-number>
</customer>

Дополнительные Информация


вы смотрели кинокомпании xStream ? Он десериализует / десериализует стандартный POJO без аннотаций или XSDs. Вы можете предоставить настройки, чтобы повлиять на то, как элементы отображаются в XML и в значительной степени работает из коробки.


вы можете написать пользовательский XmlAdapter и аннотировать поля ограниченного типа с помощью XmlJavaTypeAdapter Примечание. Основы были бы что-то вроде этого:

public enum CannotBeAnnotated { value1, value2; }
@XmlRootElement(name="client")
public class ClientClass {
    @XmlJavaTypeAdapter(Bridge.class)
    public CannotBeAnnotated;
}
@XmlRootElement(name="representation")
public class XmlType {
    @XmlValue
    public String value;
}
public class Bridge extends XmlAdapter<XmlType, CannotBeAnnotated>{
    public XmlType marshal(CannotBeAnnotated c) {
        XmlType x=new XmlType(); 
        x.value=c.name();
        return x;
    }
    public CannotBeAnnotated unmarshall(XmlType x) {
        return CannotBeAnnotated.valueOf(x.value);
    }
}

конечно, для перечислений это не было бы полезно, поскольку JAXB знает, как с ними бороться. Я просто выбрал перечисление для простоты, чтобы вы могли увидеть идею:

  1. создайте XML-представление, которое вы do управления
  2. напишите адаптер, преобразующий этот тип Java в желаемый тип
  3. комментировать "клиент" - код, ссылающийся на адаптер для нужного типа
  4. прибыль.

вы также можете использовать JibX

http://jibx.sourceforge.net/