1

編集:このコードは問題ありません。疑似コードに存在しないロジックのバグがどこかに見つかりました。私はJavaの経験が不足していることを非難していました。

以下の疑似コードでは、表示されている XML を解析しようとしています。ばかげた例かもしれませんが、私のコードは大きすぎたり具体的すぎたりして、誰もそれを見て投稿された回答から学ぶことから真の価値を得ることができませんでした. だから、これはもっと面白いですし、うまくいけば他の人も私と同じように答えから学ぶことができます.

私は Java は初めてですが、経験豊富な C++ プログラマーであるため、私の問題は Java 言語の理解にあると信じています。

問題: パーサーが終了すると、Vector は初期化されていない Cow でいっぱいです。デフォルトの容量で牛のベクターを作成します (C++ STL ベクターのようなものであれば、「サイズ」には影響しません)。解析後に Cow Vector の内容を出力すると、正しいサイズの Vector が表示されますが、すべての値が設定されていないように見えます。

情報: Vectorフィールドを持たない他のパーサーでこれを成功させましたが、この場合、Vector を使用して Cow プロパティを蓄積したいと思います。

MoreInfo: ジェネリック (Vector< Cow >) は使用できないので、そこを指摘しないでください。:)

前もって感謝します。

<pluralcow>
        <cow>
            <color>black</color>
            <age>1</age>
        </cow>
        <cow>
            <color>brown</color>
            <age>2</age>
        </cow>
        <cow>
            <color>blue</color>
            <age>3</age>
        </cow>
</pluralcow>

public class Handler extends DefaultHandler{
    // vector to store all the cow knowledge
    private Vector  m_CowVec;

    // temp variable to store cow knowledge until
    // we're ready to add it to the vector
    private Cow     m_WorkingCow;

    // flags to indicate when to look at char data
    private boolean m_bColor;
    private boolean m_bAge;

    public void startElement(...tag...)
    {
        if(tag == pluralcow){   // rule: there is only 1 pluralcow tag in the doc
                // I happen to magically know how many cows there are here.             
                m_CowVec = new Vector(numcows);
        }else if(tag == cow ){  // rule: multiple cow tags exist
            m_WorkingCow = new Cow();
        }else if(tag == color){ // rule: single color within cow
            m_bColor = true;
        }else if(tag == age){   // rule: single age within cow
            m_bAge = true;
        }
    }

    public void characters(...chars...)
    {
        if(m_bColor){
            m_WorkingCow.setColor(chars);   
        }else if(m_bAge){
            m_WorkingCow.setAge(chars);
        }
    }

    public void endElement(...tag...)
    {
        if(tag == pluralcow){
            // that's all the cows
        }else if(tag == cow ){
            m_CowVec.addElement(m_WorkingCow);      
        }else if(tag == color){
            m_bColor = false;
        }else if(tag == age){
            m_bAge = false;
        }
    }
}
4

4 に答える 4

3

Cowsが初期化されていないと言うとき、Stringプロパティはnullに初期化されていますか?または空の文字列?

これは擬似コードであるとおっしゃっていましたが、いくつかの潜在的な問題を指摘したいと思います。

public void startElement(...tag...)
    {
        if(tag == pluralcow){   // rule: there is only 1 pluralcow tag in the doc
                // I happen to magically know how many cows there are here.                     
                m_CowVec = new Vector(numcows);
        }else if(tag == cow ){  // rule: multiple cow tags exist
                m_WorkingCow = new Cow();
        }else if(tag == color){ // rule: single color within cow
                m_bColor = true;
        }else if(tag == age){   // rule: single age within cow
                m_bAge = true;
        }
    }

ここでは、tag == ...の代わりにtag.equals(...)を使用する必要があります。

public void characters(...chars...)
{
    if(m_bColor){
            m_WorkingCow.setColor(chars);   
    }else if(m_bAge){
            m_WorkingCow.setAge(chars);
    }
}

あなたがこれを知っていると思いますが、このメソッドは実際には開始インデックスと終了インデックスを持つ文字バッファで呼び出されます。

また、文字(...)は、単一のテキストブロックに対して複数回呼び出され、呼び出しごとに小さなチャンクを返す可能性があることにも注意してください:http: //java.sun.com/j2se/1.4.2/docs/api/org/xml /sax/ContentHandler.html#characters(char[],%20int,%20int)

「...SAXパーサーは、すべての連続する文字データを1つのチャンクで返す場合もあれば、複数のチャンクに分割する場合もあります...」

あなたが提供した単純な例でその問題に遭遇することはないと思いますが、これはより複雑な問題の単純化されたバージョンであるとも述べました。元の問題で、XMLが大きなテキストブロックで構成されている場合、これは考慮すべき点です。

最後に、他の人が述べているように、可能であれば、XMLマーシャリングライブラリ(たとえば、JAXB、Castor、JIBX、XMLBeans、XStreamなど)を検討することをお勧めします。

于 2008-10-26T09:11:19.353 に答える
1

コードは私にはうまく見えます。各関数の開始時にブレークポイントを設定し、デバッガーで監視するか、print ステートメントを追加します。私の腸はcharacters()、呼び出されていないかsetColor()setAge()正しく機能していないことを示していますが、それは単なる推測です。

于 2008-10-26T05:11:24.690 に答える
0

私はこのデザインの大ファンではないと言わざるを得ません。しかし、あなたのキャラクターが今までに呼び出されたことはありますか? (おそらく、いくつかの system.outs が役立つでしょう)。呼び出されない場合は、初期化されていない牛になってしまいます。

また、検証の問題に対してより堅牢である必要があるため、このような XML パーサーを自分で実装しようとはしません。

SAX または DOM4J を使用できますが、Apache ダイジェスターを使用することもできます。

于 2008-10-26T05:17:34.710 に答える
0

また、スキーマがある場合は、JaxB または別のコード ジェネレーターを使用して、XML インターフェース コードの開発を高速化します。コード ジェネレーターは、SAX や DOM4J を直接操作することの複雑さの多くを隠しています。

于 2008-10-26T06:55:47.507 に答える