如何将单个JavaBean打包成具有现有注释的复杂XML文档?

如何将单个JavaBean打包成具有现有注释的复杂XML文档?,java,xml,annotations,jaxb,Java,Xml,Annotations,Jaxb,我有一个javabean,它已经为JPA做了注释,我也希望将其存储为XML。目标是使用注释管理从bean到XML的映射 我在网上看到了有关指定模式和让JAXB生成类的相关主题,但我不想这样做 我一直在考虑使用JAXB注释,但似乎需要为每个子元素创建新的类。我试图避开这个问题,让注释展示如何构造子元素。JAXB似乎不想这样做 这有可能吗?怎么可能?我需要自己做注释而忘记JAXB吗 具体例子 豆子: 解析: JAXBContext context = JAXBContext.newInstance(

我有一个javabean,它已经为JPA做了注释,我也希望将其存储为XML。目标是使用注释管理从bean到XML的映射

我在网上看到了有关指定模式和让JAXB生成类的相关主题,但我不想这样做

我一直在考虑使用JAXB注释,但似乎需要为每个子元素创建新的类。我试图避开这个问题,让注释展示如何构造子元素。JAXB似乎不想这样做

这有可能吗?怎么可能?我需要自己做注释而忘记JAXB吗

具体例子 豆子:

解析:

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 version="1.0" encoding="UTF-8" standalone="yes"?>
<FIXML Acct="account_data" SID="sender"/>

当前生成的XML:

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

显然,我还没有提供足够的信息来映射子元素,但我也不确定如何提供它。我想添加一些@XmlElement注释,但我没有子对象,所有数据都在这个类中


好处是我的XML并不比这个例子复杂多少;只有少数几个元素,而且每个消息只显示一次。给我带来麻烦的是从一个bean中获取多个元素。

您可以在中使用@XmlPath扩展,我是技术负责人

模型类

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>
了解更多信息


我不知道Jaxb注释,但如果您在ExecRpt中要求一个属性,那么在ExecRpt no中有一个属性似乎很正常

我认为您对这些注释的期望有点过高。难道你不想要一个注释,它会接受一个字符串,用一个分隔符将其拆分,并生成一个子元素列表或其他东西吗


在我看来,将这些注释直接放在JPA实体上是一个糟糕的设计。有一天,您可能需要对数据库进行一些更改,以解决性能问题,例如,您无法再生成所需的xml。为什么不将您的jpa实体转换为jaxb友好的给定结构,以便保留db和编组程序?因此,在进行更改时,您只需修改转换器。

请同时阅读:顺便说一句,@XmlPath Blaise讨论的功能似乎足够强大,因此xml/实体之间的紧密耦合不会成为问题(只要您继续使用moxy/jpa),但它仍然不是最好的设计还有一个XmlJavaTypeAdapter,但不知道它是否适合您的需要……我认为这并不能真正解决问题。在模型之间引入转换步骤会增加更多代码来维护/测试,而JPA模型的更改仍然需要更改转换逻辑。XmlAdapter将是使用任何JAXB实现解决此问题的一种方法。有关XmlAdapter的更多信息,请参阅:谢谢,这正是我所需要的。我对将jaxb.properties文件与我的类混合持怀疑态度,但结果超过了我的任何怀疑。