代码生成-XML到Java

代码生成-XML到Java,java,xml,xsd,code-generation,Java,Xml,Xsd,Code Generation,我正在寻找一种从XML动态生成(意味着每次其他java类)java类的方法。初始XML基于XSD,但结果类应为bean。 例如: XSD(仅在短期内): 基本上是一个带有实现类名和配置项列表的简单参数 XML(示例): 怎样才能做到呢?我迷路了。我看了JAXB、XStream、XMLBeans(可能还不够好),但它似乎不是我所需要的 “复杂的输入XML”可能会通过XSLT(我认为)转换为简单的XML <desired.class.name.APPConfig> <ipOfSo

我正在寻找一种从XML动态生成(意味着每次其他java类)java类的方法。初始XML基于XSD,但结果类应为bean。 例如:

XSD(仅在短期内):

基本上是一个带有实现类名和配置项列表的简单参数

XML(示例):

怎样才能做到呢?我迷路了。我看了JAXB、XStream、XMLBeans(可能还不够好),但它似乎不是我所需要的

“复杂的输入XML”可能会通过XSLT(我认为)转换为简单的XML

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

8.8.8.8
1099
但是除了什么呢

提前谢谢 亚历克斯

另外,在尝试了一些技术之后,我接受了一个挑战,即使用XSLT将XML转换为文本(语法上是Java类)。以前使用maven和定义的XSD进行的XML验证。

感谢大家的帮助。

您误解了XSLT在这种情况下的作用

XSLT可以用于将一个XML文档转换为另一个XML文档,也可以用于将一个XML文档转换为另一个非XML文档。您希望创建一个XSLT,将“源XML”转换为java代码

。希望它能让您深入了解如何将XML转换为非XML输出


顺便说一句,您很快就会发现XML对于大多数编程语言来说都是一个糟糕的包装器。

我不知道有什么神奇的工具可以做到这一点,但如果您准备实际编写一些代码,那么我想您可以:

  • 拼凑一些东西来解析XML(使用内置的/API相当容易),并写出相应的Java源代码
  • 使用

您可以从解析XML开始(使用许多可用的解析器之一,比如XPath),并相应地生成代码

您可以使用一个非常好的Java代码解析器/生成器,名为。这个名称有点误导,因为它还可以用来从头创建新的编译单元

例如:

 /**
     * 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;
    }

我相信这项工作可以用来自世界各地的一种工具来完成。我想没有人打算在运行时使用它们,可能只有一次,但我仍然没有看到任何东西可以阻止您将其嵌入到运行时代码中


顺便说一句,我不太明白为什么要在运行时生成类。如果您在运行时生成一个类,那么它与普通的
Map
property Map有何不同(或者与之相比,它带来了什么价值?

当我过去编写代码生成器时,我所做的是首先创建一个中间步骤-一个用于生成代码的各种类型的模型。然后有两个步骤:

  • 使用您喜爱的XML解析库将XML解析到模型中
  • 使用模板引擎(速度是我最喜欢的)从模型生成代码

  • 这很好,因为它更容易测试,如果您决定更改XML以获得更容易阅读的DSL,那么更改就容易多了。

    您想动态创建Java类吗?您想用它们做什么,因为它们在编译时不为人所知,除非使用反射,否则无法访问它们……此工具应是开发前设置的一部分。一旦创建了类,用户就可以导入它们。为什么JAXB不做这项工作呢?配置JAXB Maven插件/Ant目标,从您需要的所有XSD创建所有类。我只有一个通用XSD,我需要创建N个未知类,它们应该是bean。如果属性是固定的,为什么不创建一个抽象类,在最初的一个问题中,我注意到了将复杂XML(适合XSD的)转换为简单XML(简单XML应该很容易转换为bean)的可能性。另一方面,XSLT可以将XML转换为纯文本(可以是JAVA…)。谢谢你的链接,谢谢你的回复。在项目构建阶段生成Java类,而不是在运行时生成。一旦创建了类,开发人员就应该将它们导入到代码中。啊,我明白了。我被“动态”这个词弄糊涂了。无论哪种方式,答案都是一样的。我查看了一个JiBX库,如果我理解正确的话,它们提供了Java->XSD和XSD->Java,这对我的需求来说不是很好,因为它将始终生成相同的类。。。我需要它能够从XMLs生成不同的类(匹配XSD,但仅用于验证),这些类应该是一个bean(而不是一些具有配置项列表的通用类)。如果我遗漏了JiBX的一些内容,请纠正我。我不知道您还需要多少详细信息,但您是否搜索了“Java XPath API”和“Java编译器API”?我想到的工具是“编写几行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;
    }
    
    <desired.class.name.APPConfig>
     <ipOfSomeServer>8.8.8.8</ipOfSomeServer>
     <portOfSomeServer>1099</portOfSomeServer>
    </desired.class.name.APPConfig>
    
     /**
         * 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;
        }