Java Vector Field(プライベートメンバー)アキュムレーターに牛が保存されません!

StackOverflow https://stackoverflow.com/questions/237561

  •  04-07-2019
  •  | 
  •  

質問

編集:このコードは問題ありません。擬似コードには存在しない論理バグを見つけました。 Javaの経験が足りないことを非難していました。

下の擬似コードでは、表示されているXMLを解析しようとしています。馬鹿げた例かもしれませんが、私のコードは大きすぎて特定できないため、投稿された回答から実際の価値を引き出すことはできません。ですから、これはもっと面白く、うまくいけば他の人も答えから学ぶことができます。

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

問題:パーサーが終了すると、ベクターに初期化されていない牛がいっぱいになります。デフォルトの容量で牛のベクターを作成します(C ++ STLベクターのようなものである場合、<!> quot; size <!> quotには影響しません)。解析後にCow Vectorのコンテンツを出力すると、Vectorのサイズは適切ですが、すべての値が設定されていないように見えます。

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

MoreInfo:ジェネリック(Vector <!> lt; Cow <!> gt;)を使用できないので、そこに私を向けないでください。 :)

事前に感謝します。

<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;
        }
    }
}
役に立ちましたか?

解決

コードは私には問題ありません。各関数の開始点にブレークポイントを設定し、デバッガーで監視するか、いくつかのprintステートメントを追加します。私の腸は、characters()が呼び出されていないか、setColor()setAge()が正しく動作しないことを教えてくれますが、それは単なる推測です。

他のヒント

牛が初期化されていないという場合、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);
    }
}

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

また、characters(...)は1つのテキストブロックに対して複数回呼び出すことができ、各呼び出しで小さなチャンクを返すことに注意してください。 http://java.sun.com/j2se/1.4.2/docs/api/org/xml/sax/ContentHandler.html#characters(char []、%20int、%20int)

  

<!> quot; ... SAXパーサーは、連続するすべてを返すことがあります   単一チャンクの文字データ、または   彼らはそれをいくつかのチャンクに分割するかもしれません... <!> quot;

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

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

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

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

SAXまたはDOM4Jを使用できます。さらに良いのは、Apacheダイジェスターを使用することです。

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top