2010-12-08 117 views
1

我想找到一个库,允许我把一个XML的内容放入一个JavaBean(像Digester,Jaxb,JIXB等),但我需要它是运行时而不是在编译时或字节码生成)并使用某种映射文件。XML到Java的映射工具 - 与映射描述符

这个想法将像Hibernate的HBM映射文件一样,这是一种指定哪个XML元素进入哪个Java属性的方法。我目前正在使用Digester,但我想要更简单的规则文件。

这应该也适用于1.4 JDK,所以注释不会真的做到(但为了完整性,我会考虑这种回应)。要恢复,我需要一个运行时工具,它基于某种类型的XML描述符执行XML到Java,类似于(取自JIXB),但是在运行时(即将它传递给XML,将Java类传递给输出对象和映射描述符):

alt text

你知不知道这样的图书馆吗?

谢谢!

回答

0

试试Castor。它能够从DTD(也可能来自XSD)生成Java代码。所以,你可以在运行时生成代码然后编译它。

顺便再次检查JAXB。我相信它也可以做到这一点。

+1

我已经有了Java类和XML文件。不能改变这一点,所以我需要用一个描述符将它们粘合在一起,说明“this goes here”。生成东西并不是一个真正的选择。感谢您的回答! – user1010 2010-12-08 09:27:36

+0

我想我会试试Castor的“映射模式”。似乎没有任何代码生成就做我所需要的。再次感谢。 – user1010 2010-12-09 08:34:56

2

尝试使用XSLT。

您可以输入XML文件并将其转换为另一个XML文件,该文件将作为Jaxb/XmlBeans/...的输入来填充您的bean。

XSL文件将是描述映射的“运行时”配置。

输入XML ---(XSLT)--->豆XML ---(JAXB)--->的Java bean

0

休眠实际上有XML映射了一些支持。有关更多信息,请参见the doc。我前段时间做过一个PoC,发现它对文档有点缺乏。我没有找到如何正确使用名称空间。

我们最终使用罗马,因为我们只需要用自定义命名空间解析/生成Atom提要。但我不认为罗马会解决你的问题。映射在Java代码中完成,并且在解析/生成RSS/Atom时受到限制...

祝你好运!如果你最终使用Hibernate,我很想知道它是如何为你工作的!

0

Apache Commons Digester应该可能是一个有趣的工具来考虑。它可以满足您的需求,即采用XML并将其转换为Java bean。

0

EclipseLink JAXB (MOXy)(我是技术负责人)有一个XML映射文件。对于您的示例映射文件将是:

绑定。XML

<xml-bindings 
    xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm" 
    package-name="blog.bindingfile"> 
    <java-types> 
     <java-type name="Customer"> 
      <xml-root-element/> 
      <xml-type prop-order="person street city state zip phone"/> 
     </java-type> 
     <java-type name="Person"> 
      <xml-type prop-order="customerNumber firstName lastName"/> 
      <java-attributes> 
       <xml-element java-attribute="customerNumber" name="cust-num"/> 
       <xml-element java-attribute="firstName" name="first-name"/> 
       <xml-element java-attribute="lastName" name="last-name"/> 
      </java-attributes> 
     </java-type> 
    </java-types> 
</xml-bindings> 

域模型

这将映射以下类别:

package blog.bindingfile; 

public class Customer { 

    public Person person; 
    public String street; 
    public String city; 
    public String state; 
    public Integer zip; 
    public String phone; 

} 

package blog.bindingfile; 

public class Person { 

    public int customerNumber; 
    public String firstName; 
    public String lastName; 

} 

XML

/从以下XML:

<?xml version="1.0" encoding="UTF-8"?> 
<customer> 
    <person> 
     <cust-num>123456789</cust-num> 
     <first-name>John</first-name> 
     <last-name>Smith</last-name> 
    </person> 
    <street>12345 Happy Lane</street> 
    <city>Plunk</city> 
    <state>WA</state> 
    <zip>98059</zip> 
    <phone>888.555.1234</phone> 
</customer> 

演示代码

这表现在:

package blog.bindingfile; 

import java.io.File; 
import java.util.HashMap; 
import java.util.Map; 

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

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, new File("binding.xml")); 
     JAXBContext jc = JAXBContext.newInstance("blog.bindingfile", Customer.class.getClassLoader() , properties); 

     Unmarshaller unmarshaller = jc.createUnmarshaller(); 
     Customer customer = (Customer) unmarshaller.unmarshal(new File("input.xml")); 

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

} 

jaxb.properties

要使用莫西作为JAXB实现需要包括jaxb.properties与您的文件具有以下条目的模型类:

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

注意

此示例使用在即将到来的EclipseLink 2.2发行版中的简化引导。对于使用的EclipseLink 2.1的例子看看: