0

variusエンティティタイプを記述した一連のXMLファイルがあります。ミックスインに基づく実装を使用して、これらのXMLファイルをJavaクラス(ソースコードなので、コンパイルされていることを確認できます)に変換したいと思います。

例:

村人を説明するXMLファイル:

<?xml version="1.0" encoding="utf-8" ?>
<entity>
    <id>1</id>
    <gathers>
        <rate>12</rate>
    </gathers>
    <moves>
        <speed>4</speed>
    </moves>
</entity>

次のクラスになる必要があります。

public class Villager implements Gathers, Moves {

    private final Gathers gathers;
    private final Moves moves;

    int getId() {

        return 1;
    }

    @Override
    public int getSpeed() {

        return this.moves.getSpeed();
    }

    @Override
    public int getRate() {

        return this.gathers.getRate();
    }

    public Villager() {

        super();

        this.moves = new MovesMixin(4);
        this.gathers = new GathersMixin(12);
    }
}

新しいプロパティをカバーするように簡単に拡張できる方法でこれを実行したいと思います。

このようなことを行うことができる既存のパッケージ/ツールはありますか?


テンプレートを使用した更新された例:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform version="1.0"
                xmlns="http://www.w3.org/1999/xhtml"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/> 
<xsl:template match="entity">
/*
 * DO NOT MODIFY
 * This is an automatically generated class.  
 */
package xslt.entities;

import xslt.*;

public strictfp final class <xsl:value-of select="typeName"/> implements <xsl:apply-templates select="moves" mode="implement"/><xsl:apply-templates select="gathers" mode="implement"/><xsl:apply-templates select="shoots" mode="implement"/>Entity {
    <xsl:apply-templates select="moves" mode="mixin"/>
    <xsl:apply-templates select="gathers" mode="mixin"/>
    <xsl:apply-templates select="shoots" mode="mixin"/>
    public <xsl:value-of select="typeName"/>() {

        super();
    }
}
</xsl:template>

<xsl:template match="moves" mode="implement">Moves, </xsl:template>

<xsl:template match="gathers" mode="implement">Gathers, </xsl:template>

<xsl:template match="shoots" mode="implement">Shoots, </xsl:template>

<xsl:template match="moves" mode="mixin">
    private final Moves moves = new MovesMixin(<xsl:value-of select="speed"/>);

    @Override
    public int getSpeed() {

        return this.moves.getSpeed();
    }
</xsl:template>

<xsl:template match="gathers" mode="mixin">
    private final Gathers gathers = new GathersMixin(<xsl:value-of select="rate"/>);

    @Override
    public int getRate() {

        return this.gathers.getRate();
    }
</xsl:template>

<xsl:template match="shoots" mode="mixin">
    private final Shoots shoots = new ShootsMixin(<xsl:value-of select="range"/>);

    @Override
    public int getRange() {

        return this.shoots.getRange();
    }
</xsl:template>

</xsl:transform>
4

2 に答える 2

1

基本的に、アスペクトで定義された新しいメンバー (フィールド、メソッド、コンストラクター) を既存の型に追加できます。

http://www.eclipse.org/aspectj/doc/next/progguide/language-interType.html

XML記述子を理解するものではありませんが、確かにJavaでミックスインを実装する方法であるため、おそらくそれを利用できます.

于 2013-02-17T21:27:40.443 に答える
0

XML から Java を生成する方法はたくさんあります。ここでの私の例では、ANT から呼び出された XSLT を使用しています。

├── build.xml
└── src
    ├── xml
    │   └── entity.xml
    └── xsl
        └── java.xsl

build.xml

<project name="Generate Java" default="generate">

    <target name="generate">
        <xslt style="src/xsl/java.xsl" basedir="src/xml" destdir="build/java" extension=".java"/>
    </target>

    <target name="clean">
        <delete dir="build"/>
    </target>
</project>

java.xsl

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
                xmlns="http://www.w3.org/1999/xhtml"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                >

<xsl:output method="text"/> 

<!-- 
==============================
Match the root tag 
==============================
-->
<xsl:template match="entity">
public class Villager implements Gathers, Moves {

    private final Gathers gathers;
    private final Moves moves;

    int getId() {

        return <xsl:value-of select="id"/>;
    }

    @Override
    public int getSpeed() {

        return this.moves.getSpeed();
    }

    @Override
    public int getRate() {

        return this.gathers.getRate();
    }

    public Villager() {

        super();

        this.moves = new MovesMixin(<xsl:value-of select="moves/speed"/>);
        this.gathers = new GathersMixin(<xsl:value-of select="gathers/rate"/>);
    }
}
</xsl:template>

</xsl:stylesheet>

アップデート

次のスタイルシート拡張機能は、ソース コード生成を入力 XML に応じてより動的にする方法を示しています。

ノート:

  • 生成された Java には構文エラーが含まれています。申し訳ありませんが、ほぼ完成しています。

java.xsl

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
                xmlns="http://www.w3.org/1999/xhtml"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                >

<xsl:output method="text"/> 

<!-- 
==============================
Match the root tag 
==============================
-->
<xsl:template match="entity">
public class Villager implements <xsl:apply-templates select="gathers|moves" mode="class-implements"/> {

    private final Gathers gathers;
    private final Moves moves;

    int getId() {

        return <xsl:value-of select="id"/>;
    }

    <xsl:apply-templates select="gathers|moves" mode="class-getters"/>

    public Villager() {

        super();

        <xsl:apply-templates select="gathers|moves" mode="mixins"/>
    }
}
</xsl:template>

<!-- 
==============================
Match the gather tag 
==============================
-->
<xsl:template match="gathers" mode="class-implements">
    <xsl:text>Gathers,</xsl:text>
</xsl:template>

<xsl:template match="gathers" mode="class-getters">
    @Override
    public int getRate() {

        return this.gathers.getRate();
    }
</xsl:template>

<xsl:template match="gathers" mode="mixins">
        this.gathers = new GathersMixin(<xsl:value-of select="rate"/>);
</xsl:template>

<!-- 
==============================
Match the gather tag 
==============================
-->
<xsl:template match="moves" mode="class-implements">
    <xsl:text>Moves,</xsl:text>
</xsl:template>

<xsl:template match="moves" mode="class-getters">
    @Override
    public int getSpeed() {

        return this.moves.getSpeed();
    }
</xsl:template>

<xsl:template match="moves" mode="mixins">
        this.moves = new MovesMixin(<xsl:value-of select="speed"/>);
</xsl:template>

</xsl:stylesheet> 
于 2013-02-17T22:32:20.173 に答える