在Eclipse中生成Java代码?

15

有没有人知道如何自动从xml或json文件中生成Java源代码,在eclipse中进行?

我想做的一个很好的例子是Google Android sdk所做的:他们从resources自动生成了R类。

每次在Eclipse中保存资源文件时,都会自动重新生成R类。

更新:例子:

 <tags>
     <tag id="ALPHA">
         <description>The first alpha tag.</description>
         <value>231232</value>
     </tag>
     <tag id="BETA">
         <description>This is the beta tag.</description>
         <value>231232</value>
     </tag>

然后在我生成的Java类中,比如R类,我会有类似以下的内容:

R.tags.ids.ALPHA //refers to an enum value for example
R.tags.values.ALPHA //refers to final int with avlue 231232
R.tags.descriptions.ALPHA //refers to the String with description

谢谢!


谢谢,但是这太庞大了,我不知道从哪里开始! - Andriy Drozdyuk
你是否只是在处理数据对象(很少或没有行为)?如果是的话,你应该使用JAXB。请查看我的答案。 - Adam Gent
你提供的例子中,“R.tags.ids.ALPHA” 不是 Java 语言,或者是 Google 的 Android SDK 将其 Java 类设计为具有公共成员访问权限,这在 Java 社区中有些不规范。很容易更新我提供的 XSLT 来处理这种非规范行为。 - Adam Gent
这种事情为什么必要,它解决了哪些问题? - Manius
下载 Eclipse 的 Android 工具,它们提供了开发时生成 R 类的功能。 - Andriy Drozdyuk
显示剩余2条评论
7个回答

4
我使用的方法是有一个XSLT文件,它可以将我的XML数据(在我的情况下是协议规范)简单地转换为Java源代码。这个XSLT转换可以很容易地在ANT任务中完成,可以包含在Eclipse的构建链中。
也许有一个插件可以完成这个特定的任务。
一些有用的链接:

3
根据您的评论以及我不推荐在Google Android Resource SDK之外进行此操作,我正在添加另一个答案。基本上,Google使用静态类(单例)的层次结构来管理资源。您需要使XSLT生成静态成员变量而不是getter和setter。
我基本上采用了我的旧答案,并将所有成员变量更改为静态。这样做时必须非常小心,因为我见过许多由于“static”修饰符的错误使用而导致的错误。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" />
    <xsl:template match="/" priority="100">
    public class <xsl:value-of select="name(node())" /> {
        <xsl:apply-templates  select="child::node()" />
    }
    </xsl:template>
    <xsl:template match="/*/*">
        public static String <xsl:value-of select="name()" />;
        public static String get<xsl:value-of select="name()" /> {
            return <xsl:value-of select=" name()" />;
        }

        public void static set<xsl:value-of select="name()" />(String value) {
            <xsl:value-of select="name()" /> = value;
        }
    </xsl:template>
</xsl:stylesheet>

如果您要处理此示例XML:
<?xml version="1.0" encoding="UTF-8"?>
<Human>
    <EyeColor>brown</EyeColor>
    <HairColor>brown</HairColor>
</Human>

你会得到类似这样的东西: public class Human {
    public static String EyeColor;

    public static String getEyeColor {
        return EyeColor;
    }

    public static void setEyeColor(String value) {
        this.EyeColor = value;
    }


    public static String HairColor;
    public static String getHairColor {
        return HairColor;
    }

    public static void setHairColor(String value) {
        this.HairColor = value;
    }


}

如果一个属性是公共的,为什么还需要getter-setter方法呢?为什么不使用常规的final静态成员呢? - Andriy Drozdyuk
1
因为如果您想使用序列化工具(如JAXB)自动读取和填充字段,您需要它们。否则,您不需要它们。实际上,一些工具允许您使用成员变量而不是getter/setter。 - Adam Gent
1
有没有办法在Eclipse中将它连接起来,以便每当我保存一个XML文件时,它就自动降下来? - Andriy Drozdyuk

2
Eclipse Modelling Framework (EMF)是您正在寻找的应用程序。我假设您有一个模型,想将其转换为代码。我可以给出一个非常具体的提示,那就是JET(Java Emitter template),您可以在此处了解更多详细信息。
另外,Eclipse引入了新的框架XPand,
围绕抽象语法开发组件的模型转换技术。 1. 模型到文本(Java Emitter Templates [JET]和Xpand) 2. 模型到模型(QVT和ATL)
这里的模型指的是XML-XSLT / UML(Rational Rose)模型。

我找不到“XPand”框架。你能提供一个链接吗? - Andriy Drozdyuk

1

从XML到JAVA,反之亦然,我强烈推荐使用JAXB。

您可以使用JAXB 2.0或更高版本从模式生成Java源代码。 或者您可以从Java生成模式。

您还可以轻松地使用Jettison使JAXB生成/消耗JSON。

您还可以使用其插件系统以Martin Fowler流畅风格或许多不同方式生成POJO。

根据您的评论进行编辑: 使用XSLT生成您的JAXB POJO:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" />
    <xsl:template match="/" priority="100">
    import javax.xml.bind.annotation.XmlRootElement;

    @XmlRootElement(name="Human")
    public class <xsl:value-of select="name(node())" /> {
        <xsl:apply-templates  select="child::node()" />
    }
    </xsl:template>
    <xsl:template match="/*/*">
        private String <xsl:value-of select="name()" />;
        public String get<xsl:value-of select="name()" /> {
            return <xsl:value-of select=" name()" />;
        }

        public void set<xsl:value-of select="name()" />(String value) {
            this.<xsl:value-of select="name()" /> = value;
        }
    </xsl:template>
</xsl:stylesheet>

如果您使用此示例XML进行处理:

<?xml version="1.0" encoding="UTF-8"?>
<Human>
    <EyeColor>brown</EyeColor>
    <HairColor>brown</HairColor>
</Human>

你会得到类似这样的东西:
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="Human")
public class Human {


    private String EyeColor;
    public String getEyeColor {
        return EyeColor;
    }

    public void setEyeColor(String value) {
        this.EyeColor = value;
    }


    private String HairColor;
    public String getHairColor {
        return HairColor;
    }

    public void setHairColor(String value) {
        this.HairColor = value;
    }


}

谢谢,但我不仅对Xml文档的模式感兴趣,还对其中包含的实际数据感兴趣。因此,如果我的Xml文档具有给定名称的属性,则希望在Java类文件中创建相同的属性。希望我表达清楚了。 - Andriy Drozdyuk
是的,但编写一个XSLT表格以创建具有正确JAXB注释的Java类并不难。 - Adam Gent
@drozzy:添加了一个XSLT示例。 - Adam Gent
谢谢Adam,但我该如何从上面获取值(棕色)?例如Human.EyeColor.brown或Human.HairColor.brown?你知道我的意思吗?这就是Android使用他们的R类的方式,例如:R.values.brown等... - Andriy Drozdyuk

1

注解使XDoclet变得不再必要。在1.5版本之前,它非常强大,但现在已经不再需要了。 - Bozho
请注意,我不想从我的代码生成XML;我想从XML或JSON生成代码。 - Andriy Drozdyuk
@drozzy 你可以使用xdoclet和注释来生成代码。 - dbyrne
@drozzy 你可以将你的XML配置转换成注释源代码,类似于你可以用注释替换Hibernate或Spring的XML配置文件。 - dbyrne
太好了,我不熟悉Hibernate或Spring。你能提供一些资源,告诉我从文本/XML文件生成注释源代码的起点在哪里吗? - Andriy Drozdyuk

1

谢谢,但首先我不知道它确切的作用是什么。它似乎将Java代码转换为文本,而我需要的是相反的 - 给定文本(XML或JSON)创建一个Java类,其中包含常量,其值在文本文件中给出。 - Andriy Drozdyuk
@drozzy 第一步是通过解析输入格式来获取某种模型,例如您可以使用JDOM解析XML,并使用JET生成Java源文件(请参见http://www.eclipse.org/articles/Article-JET/jet_tutorial1.html)。另一个选择是使用EMF的XML,并使用Xpand从EMF模型生成Java文件(http://www.openarchitectureware.org/pub/documentation/4.3.1/html/contents/xsd_tutorial.html)。 - Fabian Steeg
谢谢,但是JET教程并没有很清楚地说明JET到底是做什么的。另外EMF是什么? - Andriy Drozdyuk
使用JET,您可以定义要生成的代码的模板。从那里,JET将生成一个类来创建您的代码,使您能够将您的模型传递给该类。EMF是Eclipse建模框架:http://eclipse.org/modeling/emf - Fabian Steeg

0

是的,您可以使用xml文件来实现。创建自己的xml文件模板,然后使用preferences-java-code模板导入选择该文件,您就可以使用该模板了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接