2010-12-08 86 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的例子看看: