0

XMLの構成ファイルがあります。これは次のようになります。

<configuration>
     <database>
          <host></host>
          <port></port>
     </database>
     <queue>
           <host></host>
           <port></port>
           <type></type>
      </queue>
</configuration>

JAXB / xjcを使用してこの構成のJavaクラスを生成したいのですが、これらのクラスを生成し、これらの1つのレベルをツリーにアンマーシャリングしたいと思います。Configuration.javaを受け取るのではなく、Database.javaとQueue.javaが必要です(これらをGuice管理対象アプリケーションに個別に挿入できるようにするため)。私は(現在)これを行う方法を見ていませんが、間違ったことを探している可能性があります。


いくつかの実験の後、これらのクラスを生成し、クラスに基づいてこれらを設定して返すことができるソリューションを見つけました。

最初に、含まれているクラス(この例ではデータベースとキュー)を生成するbindings.xjbファイルを追加しました

<jaxb:bindings
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
    version="2.1">
    <jaxb:globalBindings localScoping="toplevel"/>
</jaxb:bindings>

ただし、JAXBはDatabaseクラスまたはQueueクラスを使用してマーシャリングを解除することはできず、Configurationクラスのみを使用してマーシャリングを解除できます(これは私が何かを見逃した可能性がある場所です)。できます

JAXBContext context = JAXBContext.newInstance(Configuration.class);
Unmarshaller um = context.createUnmarshaller();
Configuration conf = (Configuration) um.unmarhal(xmlFile);

だがしかし

JAXBContext context = JAXBContext.newInstance(Database.class);
Unmarshaller um = context.createUnmarshaller();
Database db = (Database) um.unmarhal(xmlFile);

ただし、ConfigurationオブジェクトのインスタンスでgetDatabase()を呼び出すことでデータベースオブジェクトを取得できるため、リフレクションを使用してこれをジェネリックにすることもできます(このコードキャッシュの結果を適切な場所に作成することは別の演習です)。

    T item = null;
    try {
        JAXBContext context = JAXBContext.newInstance(Configuration.class);
        Unmarshaller um = context.createUnmarshaller();
        Configuration conf = (Configuration) um.unmarshal(xmlFile);
        Method[] allMethods = Configuration.class.getDeclaredMethods();
        for (Method method : allMethods)
        {
            if (method.getReturnType().equals(clazz))
            {
                item = (T) method.invoke(conf);
                break;
            }
        }
    } catch (JAXBException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
        throw new ConfigException("Failure detected while loading configuration", e);
    }
    return item;

これが最善の解決策かどうかはわかりませんが(昨日JAXBを使い始めたばかりです)、目標を達成しているようです。

4

3 に答える 3

0

その特定のXMLは、typeと。Configurationのプロパティを持つクラスに対応します。これはあなたが探しているものではありませんか?DatabaseQueue

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Configuration {

    private Database database;
    private Queue queue;

}
于 2013-01-15T17:45:47.490 に答える
0

私は、質問で説明されているように、問題の解決策でこの質問に答えています。これは私の要件を満たしています:


いくつかの実験の後、これらのクラスを生成し、クラスに基づいてこれらを設定して返すことができるソリューションを見つけました。

最初に、含まれているクラス(この例ではデータベースとキュー)を生成するbindings.xjbファイルを追加しました

<jaxb:bindings
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
    version="2.1">
    <jaxb:globalBindings localScoping="toplevel"/>
</jaxb:bindings>

ただし、JAXBはDatabaseクラスまたはQueueクラスを使用してマーシャリングを解除することはできず、Configurationクラスのみを使用してマーシャリングを解除できます(これは私が何かを見逃した可能性がある場所です)。できます

JAXBContext context = JAXBContext.newInstance(Configuration.class);
Unmarshaller um = context.createUnmarshaller();
Configuration conf = (Configuration) um.unmarhal(xmlFile);

だがしかし

JAXBContext context = JAXBContext.newInstance(Database.class);
Unmarshaller um = context.createUnmarshaller();
Database db = (Database) um.unmarhal(xmlFile);

ただし、ConfigurationオブジェクトのインスタンスでgetDatabase()を呼び出すことでデータベースオブジェクトを取得できるため、リフレクションを使用してこれをジェネリックにすることもできます(このコードキャッシュの結果を適切な場所に作成することは別の演習です)。

    T item = null;
    try {
        JAXBContext context = JAXBContext.newInstance(Configuration.class);
        Unmarshaller um = context.createUnmarshaller();
        Configuration conf = (Configuration) um.unmarshal(xmlFile);
        Method[] allMethods = Configuration.class.getDeclaredMethods();
        for (Method method : allMethods)
        {
            if (method.getReturnType().equals(clazz))
            {
                item = (T) method.invoke(conf);
                break;
            }
        }
    } catch (JAXBException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
        throw new ConfigException("Failure detected while loading configuration", e);
    }
    return item;

これにより、構成パラメーターのメソッドをハードコーディングしなくても、Database.classを渡すことで、マーシャリングされていないデータベースを取得できます。これらは、マーシャリングされていないXMLファイル全体を挿入することなく、必要に応じて挿入できます。

于 2013-01-17T10:48:24.520 に答える
0

ステップ1:3つのクラスconfiguration.java、database.java、queue.javaを作成します

configuration.java

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "configuration")
public class configuration{

  @XmlElement
  private database db;
  @XmlElement
  private queue q;
  ...
}

@XmlAccessorType(XmlAccessType.FIELD)
public class database{
  @XmlElement
  private String host;
  @XmlElement
  private String port;
....
}

-------------------------

    InputStream xmlStream = new FileInputStream(config.xml);
    JAXBContext jaxbContext = JAXBContext.newInstance(configuration.class, database.class,queue.class);
    Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
                    configuration config= (configuration) jaxbUnmarshaller.unmarshal(xmlStream);

    config.getDatabase().getHost(); //returns the host
    config.getDatabase().getPort(); //returns the port

------------------------------------
于 2015-03-02T15:50:41.480 に答える