Как я могу собрать один Java-бин в сложный XML-документ с существующими аннотациями? - PullRequest
6 голосов
/ 27 января 2011

У меня есть один Java-бин, уже аннотированный для JPA, который я также хочу сохранить в виде XML, в частности FIXML . Цель состоит в том, чтобы управлять отображением от bean-компонента до XML с помощью аннотаций.

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

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

Возможно ли это и как? Нужно ли мне делать свои собственные аннотации и забыть о JAXB?

Конкретный пример

Bean:

@Entity
@XmlRootElement(name="FIXML")
@XmlType(name="ExecRpt")
public class ExecutionReport implements Serializable {
    private String account;
    private String senderCompID;

    @Column(name="ACCOUNT", nullable=true, length=64)
    @XmlAttribute(name="Acct")
    public String getAccount() {
        return this.account;
    }
    public void setAccount(String account) {
        this.account = account;
    }

    @Column(name="SENDER_COMP_ID", nullable=true, length=200)
    @XmlAttribute(name="SID")
    public String getSenderCompID() {
        return this.senderCompID;
    }
    public void setSenderCompID(String senderCompID) {
        this.senderCompID = senderCompID;
    }
}

Синтаксический:

JAXBContext context = JAXBContext.newInstance(ExecutionReport.class);
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); //pretty print XML
marshaller.marshal(executionReport, System.out);

Требуемый результирующий XML:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<FIXML>
  <ExecRpt Acct="account_data">
    <Hdr SID="sender"/>
  </ExecRpt>
</FIXML>

Текущий результирующий XML:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<FIXML Acct="account_data" SID="sender"/>

Очевидно, я пока не предоставляю достаточно информации для сопоставления дочерних элементов, но я также не уверен, как ее предоставить. Я хочу добавить аннотации @XmlElement, но у меня нет дочерних объектов, все данные находятся в этом классе.

Плюс в том, что мой XML не намного сложнее, чем этот пример; Есть только несколько элементов, и они появляются только один раз за сообщение. То, что доставляет мне неприятности, это получение нескольких элементов из одного компонента.

Ответы [ 2 ]

4 голосов
/ 27 января 2011

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

Класс модели

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

import org.eclipse.persistence.oxm.annotations.XmlPath;

@Entity
@XmlRootElement(name="FIXML")
@XmlType(name="ExecRpt")
public class ExecutionReport implements Serializable {
    private String account;
    private String senderCompID;

    @Column(name="ACCOUNT", nullable=true, length=64)
    @XmlPath("ExecRpt/@Acct")
    public String getAccount() {
        return this.account;
    }
    public void setAccount(String account) {
        this.account = account;
    }

    @Column(name="SENDER_COMP_ID", nullable=true, length=200)
    @XmlPath("ExecRpt/Hdr/@SID")
    public String getSenderCompID() {
        return this.senderCompID;
    }
    public void setSenderCompID(String senderCompID) {
        this.senderCompID = senderCompID;
    }
}

Демонстрационный код

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

public class Demo {

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

        ExecutionReport er = new ExecutionReport();
        er.setAccount("account_data");
        er.setSenderCompID("sender");

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(er, System.out);
    }

}

Результирующий XML

<?xml version="1.0" encoding="UTF-8"?>
<FIXML>
   <ExecRpt Acct="account_data">
      <Hdr SID="sender"/>
   </ExecRpt>
</FIXML>

Указание реализации EclipseLink JAXB (MOXy)

Чтобы указать MOXy как реализацию JAXB, вам нужно добавить файл с именем jaxb.properties в ваш класс ExecutionReport со следующей записью:

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

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

1 голос
/ 27 января 2011

Я не знаю аннотаций Jaxb, но если вы запрашиваете атрибут в ExecRpt, кажется нормальным иметь атрибут в ExecRpt no?

Думаю, вы ожидаете слишком много этих аннотаций.Разве вы не хотите аннотацию, которая будет принимать строку, разделять ее разделителем и генерировать список дочерних элементов или что-то в этом роде?

И мне кажется плохим дизайном помещать эти аннотации непосредственно в JPAюридические лица.Однажды вам, возможно, придется внести некоторые изменения в базу данных для проблем производительности, и вы больше не сможете генерировать желаемый xml.Почему бы не преобразовать вашу сущность jpa в данную структуру, дружественную к jaxb, чтобы сохранить приложение db and marshalling?Таким образом, при изменении вам просто нужно изменить трансформатор.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...