1

私はJavaについて読みDOMParserました。SAXParser私は DOMParser に疑いの余地はなく、人々は DOMParser よりも SAXParser を好みます。しかし、私は SAXParser の概念を理解していますが、このコードではできませんでした:

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class ReadXMLFileSAX {

 public static void main(String args[]) {

  try {

     SAXParserFactory factory = SAXParserFactory.newInstance();
     SAXParser saxParser = factory.newSAXParser();

     DefaultHandler handler = new DefaultHandler() {

     boolean bfname = false;
     boolean blname = false;
     boolean bnname = false;
     boolean bsalary = false;

     public void startElement(String uri, String localName,
        String qName, Attributes attributes)
        throws SAXException {

        System.out.println("Start Element :" + qName);

        if (qName.equalsIgnoreCase("FIRSTNAME")) {
           bfname = true;
        }

        if (qName.equalsIgnoreCase("LASTNAME")) {
           blname = true;
        }

        if (qName.equalsIgnoreCase("NICKNAME")) {
           bnname = true;
        }

        if (qName.equalsIgnoreCase("SALARY")) {
           bsalary = true;
        }

     }

     public void endElement(String uri, String localName,
          String qName)
          throws SAXException {

          System.out.println("End Element :" + qName);

     }

     public void characters(char ch[], int start, int length)
         throws SAXException {

         if (bfname) {
            System.out.println("First Name : "
                + new String(ch, start, length));
            bfname = false;
          }

          if (blname) {
              System.out.println("Last Name : "
                  + new String(ch, start, length));
              blname = false;
           }

          if (bnname) {
              System.out.println("Nick Name : "
                  + new String(ch, start, length));
              bnname = false;
           }

          if (bsalary) {
              System.out.println("Salary : "
                  + new String(ch, start, length));
              bsalary = false;
           }

        }

      };

      saxParser.parse("/home/anto/Groovy/Java/file.xml", handler);

    } catch (Exception e) {
      e.printStackTrace();
    }
  }

}

.xml ファイルは次のとおりです。

<?xml version="1.0"?>
<company>
    <staff>
        <firstname>yong</firstname>
        <lastname>mook kim</lastname>
        <nickname>mkyong</nickname>
        <salary>100000</salary>
    </staff>
    <staff>
        <firstname>low</firstname>
        <lastname>yin fong</lastname>
        <nickname>fong fong</nickname>
        <salary>200000</salary>
    </staff>
</company>

そして、プログラムを実行すると、次のような出力が得られます。

Start Element :company
Start Element :staff
Start Element :firstname
First Name : yong
End Element :firstname
Start Element :lastname
Last Name : mook kim
End Element :lastname
Start Element :nickname
Nick Name : mkyong
End Element :nickname
Start Element :salary
Salary : 100000
End Element :salary
End Element :staff
Start Element :staff
Start Element :firstname
First Name : low
End Element :firstname
Start Element :lastname
Last Name : yin fong
End Element :lastname
Start Element :nickname
Nick Name : fong fong
End Element :nickname
Start Element :salary
Salary : 200000
End Element :salary
End Element :staff
End Element :company

出力は非常にうまく見えますが、出力と混同しています! 出力の順序はどのように印刷されていますか? これを処理するのはどれですか?SAX と DOM を読んだのはこれが初めてなので、理解できませんでした。親切に助けてください。

4

7 に答える 7

2

SAX はイベントベースです。したがって、開始タグ、属性、タグ内の文字、終了タグなどを検出するたびに、ハンドラーの適切な関数が呼び出されます。

したがって、ここでの流れは次のとおりです。

  1. companyタグを見て、電話startElementしてください
  2. staffタグを見て、電話startElementしてください
  3. firstnameタグを見て、startElementそれを呼び出します(ブール値を設定します)
  4. 文字 ("yong") を参照charactersし、それらの関数を呼び出します (どのブール値が設定されているかを確認し、適切なメッセージを出力してフラグをクリアします)
  5. 終了firstnameタグを見て、endElement関数を呼び出す

...

于 2011-04-04T15:57:03.297 に答える
2

を呼び出すことによりsaxParser.parse("/home/anto/Groovy/Java/file.xml", handler);、SAX パーサーは、XML 解析を行うために実装したDefaultHandler(パラメーターとして渡したもの) を使用します。handler

SAX はイベント ベースです。これらのイベントは、パーサーが XML ドキュメントをトラバースするときに発生します。SAX パーサーは、要素 example の開始を検出する<firstname>と、メソッドを呼び出しますstartElement。次に、開始要素の本体にトラバースし、 を確認しますyong。タグで囲まれていない<>ためテキストノードとみなされ、charactersメソッドを呼び出します。別の XML 要素があればstartElement、新しい XML 要素に対して再度 を呼び出します。

最後に、SAX パーサーは、終了要素を確認してメソッド</firstname>を呼び出すまでトラバースします。endElement

これら 3 つのメソッドstartElementはすべてcharactersendElement開発者 (あなたの場合はあなた) によって実装されます。

SAX は XML ドキュメントのみをトラバースすることを忘れないでください。どのノードがどのノードの親または子であるかは記録されません。

お役に立てれば!

于 2011-04-04T16:00:32.097 に答える
0

SAXパーサーの力はそのイベントです。あなたがする必要があるのは、適切なメソッドをオーバーライド/実装することだけであり、イベントを順番に呼び出す責任は解析ライブラリにあります。

于 2011-04-04T15:54:31.863 に答える
0

パーサーは入力 XML を読み取るときstartElementに、すべての開始タグで呼び出しendElement、すべての終了タグで呼び出します。パーサーが のようなタグの内容に一致yongすると、 を呼び出しますcharacters

投稿したコードは、状態変数bfnamebsalaryなどを使用して現在解析されているタグを追跡します。charactersが呼び出されると、コードは名前、姓、または給与のどのエンティティに対して呼び出されたかを認識するため、生の文字列を適切に解読できます。

つまり、SAX パーサーを作成しているときに、実際には、XML 内のパーサーの状態を追跡するためのコールバックを作成します。つまり、現在読み取っている XML の部分です。

反対に、DOM パーサーを使用すると、XML ドキュメント全体がツリーに変換されるため、ルートからノードへ、または逆方向 (ノードからルートへ) を好きな方法でナビゲートできます。

于 2011-04-04T15:57:39.443 に答える
0

SAX パーサーは、ドキュメントを一度に 1 文字ずつ反復処理します。parse()パーサーのメソッドはHandlerオブジェクトを取ります。このオブジェクトのさまざまなメソッドは、パーサーがドキュメント内の特定の文字 (「イベント」) に遭遇したときに、パーサーによって呼び出されます。したがって、パーサーは開始タグに遭遇するたびstartElementにハンドラーのメソッドを呼び出し、終了タグに遭遇するとendElementメソッドを呼び出します。DefaultHandler のこれらのメソッドは空です。このクラスをサブクラス化し、これらのメソッドの独自の実装を提供するのはあなた次第です (上記のコード例では、Defaulthandler は匿名でサブクラス化されています)。

DOM パーサーとは異なり、SAX パーサーは要素を構築しません。開始タグと終了タグ、およびコンテンツ文字に遭遇すると、さまざまなハンドラー メソッドを起動するだけです。これらのメソッド内で、終了タグを開始タグなどにマップするロジックを提供するのはあなた次第です。これは、条件ステートメントが startElement および endElement メソッドで行っていることです。また、クラス変数blnameなどは、パーサーが現在どの要素にあるかを追跡しているだけなので、characters()メソッドに渡される文字が何に関連しているかがわかります。

于 2011-04-04T15:59:00.453 に答える
0

最後の方で、saxParser.parse()メソッドがhandlerパラメーターとして指定されていることに気付くでしょう。DefaultHandlerハンドラーは、コードで以前に定義されたのインスタンスです。SAXParser は、XML ドキュメントを解析するときに、ハンドラーで適切なメソッドを呼び出します。DefaultHandlerSAXParserに関する Javadoc を次に示します (parseメソッドに関するドキュメントを参照してください)。XML ドキュメントが解析され、ハンドラーの各メソッドが順番に呼び出されると、ハンドラー メソッドは処理された値を出力します。

于 2011-04-04T15:59:04.900 に答える
0

注文は私には問題ないようです。問題は何ですか?

start 要素と end 要素について話している場合、それは XML タグのネストを示しているだけです。「company」が「staff」の前に来て、「staff」が「firstname」の前に来ることがわかります。

最後に、個々のタグ内にデータ自体があります。そのため、最後の 3 行は次のようになります。

End Element :salary
End Element :staff
End Element :company

給料を残すので、給料はスタッフの最後の要素であり、それが会社の最後のスタッフです。

于 2011-04-04T15:56:28.367 に答える