0

Simple Framework for Javaで指定した属性の存在を調べることはできますか? 次のxmlがあるとしましょう:

<packet id="250">
  <msg id="1" uniqueAttribute1="some value" x="7" />
  <msg id="2" someStuff="123" />
  <msg id="3" someOtherStuff="abc" />
</packet>

上記のすべてのメッセージは、おそらく共通の基本クラスから継承された異なるクラスのオブジェクトに逆シリアル化する必要があります。どのメッセージがどのクラスのオブジェクトをインスタンス化するかは、属性の名前に依存する必要があります。つまり、msg に「uniqueAttribute」という名前の属性が存在する場合は、クラス Foo のオブジェクトを作成する必要があります。「someStuff」がある場合は、クラス Bar のオブジェクトなどです。

私の頭に浮かぶ唯一の方法は、クラスのオブジェクトに逆シリアル化し、例外をキャッチして再試行することです。これは悪いように聞こえます。

「Simple」フレームワークでそれが不可能な場合は、他の方法を提案できますか?

4

2 に答える 2

1

これを行うにはいくつかの方法があります。通常、訪問者または戦略を使用できます。ビジターの使用方法については、以下を参照してください。これは名前空間を使用してタイプを決定しますが、属性またはそれらの数を使用するようにこれを変更できます。

https://simple.svn.sourceforge.net/svnroot/simple/trunk/download/stream/src/test/java/org/simpleframework/xml/strategy/ClassToNamespaceVisitor.java

また、コンバーターを使用してこれを行うこともできます。チュートリアルを見てください。

于 2013-01-15T08:03:32.727 に答える
1

このような基本的な要件を備えたフレームワークの必要性はわかりませんが、それでもあなたのニーズを完全には理解していない可能性があります. 最初は、SAX 解析ハンドラーのような単純なものから始めます。完全に手作業でコーディングされ、テストされていませんが、基本的な考え方については、次を参照してください。

import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

class XmlHandler extends DefaultHandler {
    Map msgClasses = new HashMap(){{ put("uniqueAttribute1", "Foo"); put("someStuff", "Bar"); }};

    public MessageBase messageFromAttributes(final org.xml.sax.Attributes attributes) {
        for(int i=0; i<attributes.getLength(); i++) {
            if(msgClasses.contains(attributes.getValue(i))) {
                try{
                    Class msgClass = Class.forName(attributes.getValue(i));
                    return msgClass.newInstance();
                } catch(ClassNotFoundException e) {
                    return null;
                }
            }
        }
    }

    @Override
    public final void startElement(String uri, String localName, String name,
            final org.xml.sax.Attributes attributes) throws SAXException {
        if (localName.equals("msg")) {
            MessageBase message = messageFromAttributes(attributes);
        }
    }

    @Override
    public final void endElement(String uri, String localName, String name) throws SAXException {

        if (localName.equals("msg")) {
        }
    }

}

上記の例の考え方は、クラス名を特定の属性にマップし、SAX 解析イベントのインスタンス化を処理しながら、正しいクラス名を指すマッピング内の特定の属性を見つけることです。この時点で、リフレクションを使用してクラスをインスタンス化し、続行できます。必要に応じて、残りの属性値を使用してクラスを設定することもできます。

于 2013-01-14T16:06:34.633 に答える