2013-01-15 50 views
0

我在XML配置文件,它看起來像:JAXB/XJC:生成子元素類並加載它們基於類的類型

<configuration> 
    <database> 
      <host></host> 
      <port></port> 
    </database> 
    <queue> 
      <host></host> 
      <port></port> 
      <type></type> 
     </queue> 
</configuration> 

我想用JAXB/XJC生成Java類,但是我想生成這些類並將這些級別解組到樹中。我不想接收Configuration.java,而是想要一個Database.java和Queue.java(爲了能夠將這些分別注入Guice託管的應用程序中)。我(目前)沒有看到這樣做的任何方式,但可能正在尋找錯誤的東西。


一些實驗後,我已經找到了解決產生這些類和能填充並返回這些基於類:

首先,我添加了一個bindings.xjb文件,該文件將生成包含類(數據庫和隊列在該示例中)

<jaxb:bindings 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" 
    version="2.1"> 
    <jaxb:globalBindings localScoping="toplevel"/> 
</jaxb:bindings> 

然而,JAXB不能解組使用數據庫或Queue類,僅配置類(這是我可能已經錯過的東西)。我可以做

JAXBContext context = JAXBContext.newInstance(Configuration.class); 
Unmarshaller um = context.createUnmarshaller(); 
Configuration conf = (Configuration) um.unmarhal(xmlFile); 

但不

JAXBContext context = JAXBContext.newInstance(Database.class); 
Unmarshaller um = context.createUnmarshaller(); 
Database db = (Database) um.unmarhal(xmlFile); 

但是,因爲我可以通過配置對象的實例調用getDatabase()獲取數據庫對象,這也可以被泛型使用反射(在適當的地方進行這項代碼緩存結果是另一種運動):

T item = null; 
    try { 
     JAXBContext context = JAXBContext.newInstance(Configuration.class); 
     Unmarshaller um = context.createUnmarshaller(); 
     Configuration conf = (Configuration) um.unmarshal(xmlFile); 
     Method[] allMethods = Configuration.class.getDeclaredMethods(); 
     for (Method method : allMethods) 
     { 
      if (method.getReturnType().equals(clazz)) 
      { 
       item = (T) method.invoke(conf); 
       break; 
      } 
     } 
    } catch (JAXBException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { 
     throw new ConfigException("Failure detected while loading configuration", e); 
    } 
    return item; 

我不知道這是最好的解決方案(我只開始與JAXB昨日)的工作,但似乎到f我的目標。

+0

既然你知道你在解組Configuration'的'實例不需要要像反思一樣動態。你知道什麼屬性和他們的類型已經。 –

+0

此外,如果我將Database.class或Queue.class傳遞給此方法,則可以擁有此方法提供的那些副本,但不限於在任何需要使用它的位置注入應用程序配置的完整副本。 –

回答

0

我回答這個問題,我解決了問題,在這個問題的討論。這符合我的要求:


一些實驗後,我已經找到了解決產生這些類和能填充並返回這些基於類:

首先,我添加了一個bindings.xjb文件這將產生包含的類(數據庫和隊列在該示例中)

<jaxb:bindings 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" 
    version="2.1"> 
    <jaxb:globalBindings localScoping="toplevel"/> 
</jaxb:bindings> 

然而,JAXB不能使用數據庫或Queue類解組,僅配置類(這是我可能已經錯過的東西)。我可以做

JAXBContext context = JAXBContext.newInstance(Configuration.class); 
Unmarshaller um = context.createUnmarshaller(); 
Configuration conf = (Configuration) um.unmarhal(xmlFile); 

但不

JAXBContext context = JAXBContext.newInstance(Database.class); 
Unmarshaller um = context.createUnmarshaller(); 
Database db = (Database) um.unmarhal(xmlFile); 

但是,因爲我可以通過配置對象的實例調用getDatabase()獲取數據庫對象,這也可以被泛型使用反射(在適當的地方進行這項代碼緩存結果是另一種運動):

T item = null; 
    try { 
     JAXBContext context = JAXBContext.newInstance(Configuration.class); 
     Unmarshaller um = context.createUnmarshaller(); 
     Configuration conf = (Configuration) um.unmarshal(xmlFile); 
     Method[] allMethods = Configuration.class.getDeclaredMethods(); 
     for (Method method : allMethods) 
     { 
      if (method.getReturnType().equals(clazz)) 
      { 
       item = (T) method.invoke(conf); 
       break; 
      } 
     } 
    } catch (JAXBException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { 
     throw new ConfigException("Failure detected while loading configuration", e); 
    } 
    return item; 

這讓我通過傳遞Database.class無需hardcod得到一個解組數據庫用於永遠配置參數的方法。然後可以在需要時注入這些內容,而無需注入整個未編組的XML文件。

0

該特定XML將對應於具有DatabaseQueue類型屬性的Configuration類。這不是你要找的嗎?

@XmlRootElement 
@XmlAccessorType(XmlAccessType.FIELD) 
public class Configuration { 

    private Database database; 
    private Queue queue; 

} 
+0

不完全。我正在尋找額外生成單獨的類數據庫和隊列(編輯:不能在評論中放置換行符)。我設法想出了一個解決方案,它通過JAXB生成這些類,然後是基於反射的解決方案,以便能夠在解組到Configuration之後返回填充的類,並將更新問題以供其他人查找/可能會表現出更好的做事方式。 –

+0

你的意思是生成頂級類而不是嵌套類嗎?如果是這樣,請查看:http://blog.bdoughan.com/2011/07/jaxb-xjc-and-nested-classes.html –

+0

@CharlesA - 如果您只是想解組'數據庫'和'隊列'對象,以下內容將有所幫助:http://blog.bdoughan.com/2012/08/handle-middle-of-xml-document-with-jaxb.html –

0

第一步:創建3班configuration.java,database.java,queue.java

configuration.java

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlRootElement(name = "configuration") 
public class configuration{ 

    @XmlElement 
    private database db; 
    @XmlElement 
    private queue q; 
    ... 
} 

@XmlAccessorType(XmlAccessType.FIELD) 
public class database{ 
    @XmlElement 
    private String host; 
    @XmlElement 
    private String port; 
.... 
} 

------------------------- 

    InputStream xmlStream = new FileInputStream(config.xml); 
    JAXBContext jaxbContext = JAXBContext.newInstance(configuration.class, database.class,queue.class); 
    Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); 
        configuration config= (configuration) jaxbUnmarshaller.unmarshal(xmlStream); 

    config.getDatabase().getHost(); //returns the host 
    config.getDatabase().getPort(); //returns the port 

------------------------------------ 
相關問題