2011-02-15 133 views
2

我正在尋找一種從XML動態生成(意味着,每次其他java類)Java類的方法。最初的XML基於XSD,但結果類應該是一個bean。 實施例:代碼生成 - XML到Java

XSD(只是不久):

Configuration->configuration-item->name 
            ->value 
            ->type 
            ->scope 
       ->impl-class-info 

基本上一個簡單PARAM與實現類名稱和配置項

XML(實施例)的列表:

<configuration> 
<impl-class-info>desired.class.name.APPConfig</impl-class-info> 
<configuration-item> 
    <name>ipOfSomeServer</name> 
    <type>string</type> 
    <value>8.8.8.8</value> 
    <scope></scope> 
</configuration-item> 

<configuration-item> 
    <name>portOfSomeServer</name> 
    <type>string</type> 
    <value>1099</value> 
    <scope></scope> 
</configuration-item> 
</configuration> 

生成的java類應該是這樣的:

package desired.class.name; 

import xxx.xxx.xxx.ConfigurationElement; 

public class APPConfig extends ConfigurationElement { 

private String ipOfSomeServer; 
private String portOfSomeServer; 

public void setIpOfSomeServer(String ipOfSomeServer){ 
    this.ipOfSomeServer = ipOfSomeServer; 
} 
public void setPortOfSomeServer(String portOfSomeServer){ 
    this.portOfSomeServer = portOfSomeServer; 
} 

public String getPortOfSomeServer(){ 
    return this.portOfSomeServer; 
} 

public String getIpOfSomeServer(){ 
    return this.ipOfSomeServer; 
} 

怎麼辦?我迷路了。我看JAXB,XStream,XMLBeans(可能不夠好),但它似乎並不是我所需要的。

的 「複雜的輸入XML」 也許通過XSLT轉換(我認爲),以一個簡單的

<desired.class.name.APPConfig> 
<ipOfSomeServer>8.8.8.8</ipOfSomeServer> 
<portOfSomeServer>1099</portOfSomeServer> 
</desired.class.name.APPConfig> 

但還有什麼比?

在此先感謝亞歷克斯

附:在嘗試了一些技巧之後,我挑戰了使用XSLT將XML轉換爲Text(語法上的Java類)。之前使用Maven和定義的XSD進行的XML驗證。
感謝大家的幫助。

+0

你想在飛行中創建Java類嗎?你想怎麼處理它們,因爲它們在編譯時是不知道的,除了反射之外不能被訪問...... – Puce 2011-02-15 16:09:44

+0

這個工具應該是開發前設置的一部分。一旦創建了類,用戶可以導入它們。 – Alex 2011-02-15 16:42:17

+1

爲什麼JAXB不做這項工作?配置JAXB Maven插件/ Ant目標以從您需要的所有XSD創建所有類。 – Puce 2011-02-15 16:57:59

回答

0

您誤解了XSLT在這種情況下的角色。

XSLT可用於將一個XML文檔轉換爲另一個XML文檔,或者可用於將一個XML文檔轉換爲另一個非XML文檔。你想創建一個將你的「源XML」翻譯成java代碼的XSLT。

Here is an example of an XSL transform which converts XML to CSV。希望它能讓您瞭解如何將XML轉換爲非XML輸出。另外,您將很快發現XML對於大多數編程語言來說是一個糟糕的包裝。

0

我不知道一個神奇的工具,要做到這一點,但如果你準備其實寫一些代碼,那麼我想你可以:

  • 敲東西瞭解析XML(相當易與例如內置的XPath/DOM API),並吐出相應的Java源代碼
  • 使用Java編譯器API編譯它
1

您可以通過解析XML開始(使用許多可用的解析器之一,說XPath)並相應地生成代碼。

您可以使用非常好的Java代碼解析器/生成器,名稱爲Javaparser。這個名字有點讓人誤解,因爲也可以用從頭開始創建新的編譯單元。

一個例子:

/** 
    * creates the compilation unit 
    */ 
    private static CompilationUnit createCU() { 
     CompilationUnit cu = new CompilationUnit(); 
     // set the package 
     cu.setPakage(new PackageDeclaration(ASTHelper.createNameExpr("java.parser.test"))); 

     // create the type declaration 
     ClassOrInterfaceDeclaration type = new ClassOrInterfaceDeclaration(ModifierSet.PUBLIC, false, "GeneratedClass"); 
     ASTHelper.addTypeDeclaration(cu, type); 

     // create a method 
     MethodDeclaration method = new MethodDeclaration(ModifierSet.PUBLIC, ASTHelper.VOID_TYPE, "main"); 
     method.setModifiers(ModifierSet.addModifier(method.getModifiers(), ModifierSet.STATIC)); 
     ASTHelper.addMember(type, method); 

     // add a parameter to the method 
     Parameter param = ASTHelper.createParameter(ASTHelper.createReferenceType("String", 0), "args"); 
     param.setVarArgs(true); 
     ASTHelper.addParameter(method, param); 

     // add a body to the method 
     BlockStmt block = new BlockStmt(); 
     method.setBody(block); 

     // add a statement do the method body 
     NameExpr clazz = new NameExpr("System"); 
     FieldAccessExpr field = new FieldAccessExpr(clazz, "out"); 
     MethodCallExpr call = new MethodCallExpr(field, "println"); 
     ASTHelper.addArgument(call, new StringLiteralExpr("Hello World!")); 
     ASTHelper.addStmt(block, call); 

     return cu; 
    } 
0

我相信從JiBX suite工具將做的工作之一。我想沒有人會在運行時使用它們,可能只有一次,但我仍然沒有看到任何阻止您將它嵌入到運行時代碼中的內容。

順便說一句,我不太理解你爲什麼要在運行時生成一個類。如果您在運行時生成一個類,那麼與簡單的Map<String,Object>屬性圖相比它有什麼不同(或者它帶來什麼樣的價值)?

1

當我在過去編寫代碼生成器時,我所做的事情是首先創建一箇中間步驟 - 這是我希望生成代碼的各種事物的模型。然後,您有兩個步驟:使用您喜歡的XML解析庫到模型

  • 使用模板引擎(Velocity是我favority)從模型生成代碼

    1. 解析XML。

    這很好,因爲它測試起來比較容易,而且如果您決定將XML更改爲易於閱讀的DSL,則更改會更容易。