4

I'm looking for a way to generate dynamically (means, every time other java class) Java class from XML. The initial XML based on a XSD, but the result class shall be a bean. Example:

XSD (just shortly):

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

Basically one simple param with a implementation class name and list of configuration-item

XML (example):

<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>

The generated java class shall be like that:

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

How can it be done? I'm getting lost. I looked (maybe not good enough) on JAXB,XStream, XMLBeans but it doesn't seems what I need.

The "complex input XML" maybe converted by XSLT (I think) to a simple one

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

But what than?

Thanks in advance Alex

P.S. After trying a few techniques I took a challenge to use XSLT to convert XML to Text (which syntactically Java class). The XML validation made previously using maven and defined XSD.
Thanks to all for the help.

6
  • You want to create Java classes on the fly? What do you want to do with them, since they are not known at compilation time, they can't be accessed except with reflection... Commented Feb 15, 2011 at 16:09
  • This tool shall be part of pre development setup. Once classes are created user can import them. Commented Feb 15, 2011 at 16:42
  • 1
    And why doesn't JAXB do the job? Configure the JAXB Maven plugin/ Ant target to create all classes from all the XSDs you need. Commented Feb 15, 2011 at 16:57
  • I have only one generic XSD and I need to create N unknown classes and they shall be beans. Commented Feb 15, 2011 at 17:13
  • If the attributes are fixed, why not create an abstract class, and only create subclasses when needed? Commented Feb 15, 2011 at 18:48

5 Answers 5

2

You can start by parsing the XML (using one of the many available parsers, say XPath) and generate the code accordingly.

There is a very nice Java code parser/generator that you can use, named Javaparser. The name is a bit misleading because it can also be used to create new compilation units from scratch.

An example:

 /**
     * 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;
    }
Sign up to request clarification or add additional context in comments.

Comments

2

When I've written code generators in the past, what I've done is first created an intermediate step - a model for the kinds of things I wanted to generate code around. You then have two steps:

  1. Parse XML using your favorite XML parsing library into the model
  2. Use a templating engine (Velocity is my favority) for generating code from the model.

This is nice because it is easier to test, and if you decide to change out the XML for a DSL which is easier to read, the change is much easier.

Comments

1

You misunderstand the role of XSLT in this situation.

XSLT can be used to translate one XML document into another XML document, or it can be used to translate one XML document into another non-XML document. You want to create an XSLT which translates your "source XML" into java code.

Here is an example of an XSL transform which converts XML to CSV. Hopefully it will give you the insight to see how XML can be transformed to non-XML output.

As an aside, you will quickly find out that XML makes a poor wrapper for most programming languages.

1 Comment

In a original question I noticed possibility to convert complex XML (one that fits XSD) to simple XML (the simple XML shall be easily converted to a bean). On the other hand XSLT can convert XML to a plain text (which can be a JAVA ... ). Thanks for a link.
1

I don't know of a magic tool to do this, but if you're prepared to Actually Write Some Code, then I think you could:

  • knock something up to parse the XML (fairly easy with e.g. built-in XPath/DOM API) and spit out corresponding Java source code
  • use the Java Compiler API to compile it

2 Comments

Don't know how much more detail you need, but did you Google "Java XPath API" and "Java Compiler API"?
The tool I had in mind was "write a few lines of Java code" :) From the problem outline, I wasn't envisaging that that bit would be terribly complex in the grand scheme of things?
0

I believe one of the tools from the JiBX suite would do the job. I guess no-one have meant them to be used at runtime, probably once only, but still I don't see anything that would stop you from embedding it into your runtime code.

BTW, I don't quite follow why do you want a class to be generated at runtime. If you generate a class at runtime how is it different (or what value it brings when compared to) than plain Map<String,Object> property map?

3 Comments

Thanks for the response. The generation of the Java classes made in a project build phase, not in a runtime. Once classes have been created , the developer shall import them to the code.
Ah, I see. I was confused by the word "dynamically". Either way the answer remains the same.
I looked on a JiBX library, if I understand correctly they provide Java->XSD and XSD->Java , this is not so good for my needs because it will generate always the same classes ... What I need it ability to generate different classes from the XMLs (which matches XSD, but only for validation) and those classes shall be a beans (and not some general class that have list of configuration entries). Please correct me if I missed something with JiBX.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.