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 prev开发者_JS百科iously using maven and defined XSD.
Thanks to all for the help.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;
}
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:
- Parse XML using your favorite XML parsing library into the model
- 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.
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.
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
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?
精彩评论