SAXとDOMの違いは何ですか?


242

XMLパーサーに関する記事を読んだところ、SAXDOMに出会いました。

SAXはイベントベースで、DOMはツリーモデルです。これらの概念の違いは理解できません。

私が理解したことから、イベントベースとは、ノードに何らかのイベントが発生することを意味します。特定のノードをクリックすると、すべてのノードを同時にロードするのではなく、すべてのサブノードが表示されます。ただし、DOM解析の場合、すべてのノードが読み込まれ、ツリーモデルが作成されます。

私の理解は正しいですか?

誤りがある場合は訂正してください。または、イベントベースのツリーモデルをより簡単に説明してください。


DOMを正しく言えば、パーサーではありません。特定のDOMベースのソフトウェアにはマークアップ解析が組み込まれている場合と組み込まれていない場合があり、ほとんどのHTML DOMソフトウェアには組み込まれています。しかし、DOMは完全に別のものであり、シリアライゼーションフォーマットにはまったく関連付けられていない可能性があります。
Bob77

回答:


305

まあ、あなたは近いです。

SAXでは、XMLが解析されているときにイベントがトリガーさます。パーサーがXMLを解析していて、開始タグ(例<something>:)を検出すると、tagStartedイベントをトリガーします(実際のイベント名は異なる場合があります)。同様に、構文解析中にタグの終わりに到達すると、</something>トリガーされますtagEnded。SAXパーサーを使用するには、これらのイベントを処理し、各イベントで返されるデータを理解する必要があることを意味します。

DOMでは、解析中にトリガーされるイベントはありません。XML全体が解析され、(XMLのノードの)DOMツリーが生成されて返されます。解析後、ユーザーはツリー内を移動して、以前にXMLのさまざまなノードに埋め込まれていたさまざまなデータにアクセスできます。

一般に、DOMの方が使いやすいですが、使用を開始する前にXML全体を解析するオーバーヘッドがあります。


135
+1-明確化:RAMに収まる小さなファイルでDOMパーサーを使用します。大きなファイルにはSAXパーサーを使用してください。
リチャードH

@spartkymatに感謝します。しかし、SAXイベントベースの場合、SAXパーサーは特定の子ノードが特定の親の子であることを知ることができますか?それとも単に解析しますか?例えば。私は1つの<会社>がいて、子供は<従業員>です。この場合、これらの会社と従業員は解析されるだけですか、それとも会社が従業員の親であるという関係を示しますか?
user414967 2011

4
解析のみを行います。このような情報は、(ステートマシンなどを介して)自分で管理する必要があります。DOMパーサーを使用する理由(リソースが許す場合):-)。
sparkymat '26

1
@Richard H私は、RAMに収まらないほど巨大なXMLファイルを使用している人は、非常に悪いことをしていると主張します。
antred

1
40mサイズのExcelをロードし、SAXパーサーを使用する場合は200mのメモリを使用しますが、DOMパーサーを使用する場合は9gのメモリを使用します。
zhiyuan_

98

一言で言えば...

SAXS imple AのためのPI X MLは):ストリームベースのプロセッサです。いつでもメモリのごく一部しか持っておらず、イベントなどのコールバックコードを実装してXMLストリームを「嗅ぐ」tagStarted()ことができます。ほとんどメモリを使用しませんが、xpathやtraverseのような「DOM」を実行することはできません。木。

DOMD ]で文書O bject M odel):あなたはメモリに全部を読み込む-それは、大規模なメモリを独り占めです。中型サイズのドキュメントでもメモリを破壊できます。しかし、xpathを使用してツリーなどをトラバースできます。


66

ここでより簡単な言葉で:

DOM

  • ツリーモデルパーサー(オブジェクトベース)(ノードのツリー)。

  • DOMはファイルをメモリにロードしてから、ファイルを解析します。

  • 解析前にXMLファイル全体をロードするため、メモリの制約があります。

  • DOMは読み取りと書き込みです(ノードを挿入または削除できます)。

  • XMLコンテンツが小さい場合は、DOMパーサーを使用してください。

  • タグを検索したり、タグ内の情報を評価したりするため、後方検索と前方検索が可能です。これにより、ナビゲーションが容易になります。

  • 実行時に遅くなります。

サックス

  • イベントベースのパーサー(イベントのシーケンス)。

  • SAXはファイルを読み取りながら解析します。つまり、ノードごとに解析します。

  • メモリにXMLコンテンツを格納しないため、メモリの制約はありません。

  • SAXは読み取り専用です。つまり、ノードを挿入または削除できません。

  • メモリの内容が大きい場合は、SAXパーサーを使用します。

  • SAXはXMLファイルを上から下に読み取り、後方に移動することはできません。

  • 実行時に高速です。


完璧...いくつかの答えを期待していた。よくできました:)
Kunal Gupta

37

DOMベースのモデルを理解していることは正しいです。XMLファイルは全体としてロードされ、そのすべてのコンテンツは、ドキュメントが表すツリーのメモリ内表現として構築されます。これは、入力ファイルのサイズによっては、時間とメモリを消費する可能性があります。このアプローチの利点は、ドキュメントの任意の部分を簡単にクエリでき、ツリー内のすべてのノードを自由に操作できることです。

DOMアプローチは、通常、小さなXML構造に使用されます(小規模な場合は、プラットフォームの馬力とメモリの量に依存します)。いったん読み込まれると、さまざまな方法で変更およびクエリが必要になる場合があります。

一方、SAXは、実質的にあらゆるサイズのXML入力を処理するように設計されています。XMLフレームワークがドキュメントの構造を理解し、すべてのノードや属性などに潜在的に多くのオブジェクトを準備するのに苦労する代わりに、SAXはそれを完全にユーザーに任せます。

基本的には、上から入力を読み取り、特定の「イベント」が発生したときに提供するコールバックメソッドを呼び出します。イベントは、開始タグ、タグの属性、要素内のテキストの検索、または終了タグの検出にヒットする可能性があります。

SAXは頑固に入力を読み取り、この方法で何が見えるかを伝えます。必要なすべての状態情報を維持するのはあなた次第です。通常、これはある種のステートマシンを構築することを意味します。

このXML処理へのアプローチはかなり面倒ですが、非常に強力な場合もあります。ブログのフィードからニュース記事のタイトルを抽出したいとします。DOMを使用してこのXMLを読み取ると、XMLに含まれているすべての記事のコンテンツやすべての画像などが、たとえ興味がなくてもメモリに読み込まれます。

SAXを使用すると、「startTag」イベントメソッドが呼び出されるたびに、要素名が(タイトルなど)かどうかを確認できます。もしそうなら、次の「elementText」イベントが提供するものは何でも追加する必要があることを知っています。「endTag」イベント呼び出しを受け取ったら、これが「タイトル」の終了要素であるかどうかを再度確認します。その後は、入力が終了するか、「title」という名前の別の「startTag」が表示されるまで、以降のすべての要素を無視します。等々...

この方法でメガバイトとメガバイトのXMLを読み取ることができ、必要な少量のデータを抽出できます。

このアプローチのマイナス面はもちろん、どのデータを抽出する必要があるか、XML構造がどれほど複雑かによっては、自分でより多くの簿記を行う必要があることです。さらに、XMLツリー全体を手に入れることはできないため、当然、XMLツリーの構造を変更することはできません。

そのため、一般的に、SAXは特定の「クエリ」を考慮して受信する可能性のある大量のデータを処理するのに適していますが、変更する必要はありません。より高いリソース需要の。


16

リンゴとナシを比較しています。SAXは、シリアル化されたDOM構造を解析するパーサーです。多くの異なるパーサーがあり、「イベントベース」はパース方法を指します。

たぶん、小さな要約は次のとおりです:

  • ドキュメントオブジェクトモデル(DOM)は、階層、ツリーベースの文書構造を記述する抽象データモデルです。ドキュメントツリーは、ノード、つまり要素、属性、テキストノード(およびその他のノード)で構成されます。ノードには親、兄弟、および子があり、トラバースすることができます。JavaScriptを実行するために慣れているもの(偶然にもDOMとは関係ありません)。

  • DOM構造は、HTMLやXMLなどのマークアップ言語を使用して、シリアル化、つまりファイルに書き込むことができます。したがって、HTMLまたはXMLファイルには、抽象ドキュメントツリーの「書き出された」または「フラット化された」バージョンが含まれています。

  • コンピュータがファイルからDOMツリーを操作または表示するには、ファイルを逆シリアル化または解析して、メモリ内の抽象ツリーを再構築する必要があります。これが解析の出番です。

ここで、パーサーの性質について説明します。解析する1つの方法は、ドキュメント全体を読み取り、メモリ内にツリー構造を再帰的に構築し、最終的に結果全体をユーザーに公開することです。(これらのパーサーを "DOMパーサー"と呼ぶことができると思います。)これはユーザーにとって非常に便利です(PHPのXMLパーサーが行うことだと思います)が、スケーラビリティの問題があり、大きなドキュメントの場合は非常に高価になります。

一方、SAXで行われるイベントベースの解析では、ファイルを直線的に調べ、「この要素が開始した」、「その要素が終了した」などのデータの構造部分に遭遇するたびにユーザーにコールバックします。 、「ここにいくつかのテキスト」などがあります。これには、入力ファイルのサイズを気にせずにいつまでも続けることができるという利点がありますが、ユーザーに実際の処理作業(コールバック)。元の質問に戻ると、「イベントベース」という用語は、パーサーがXMLファイルをトラバースするときに発生する解析イベントを指します。

Wikipediaの記事は、 SAX解析の段階で多くの詳細を持っています。


11

この質問に対する一般的なQ&A指向の回答を提供します。

質問への回答

なぜXMLパーサーが必要なのですか?

アプリケーションのすべてをゼロから実行する必要はないため、XMLパーサーが必要です。また、非常に低レベルでありながら非常に必要な何かを実行するには、いくつかの「ヘルパー」プログラムまたはライブラリが必要です。これらの低レベルだが必要なことには、整形式のチェック、DTDまたはスキーマ(パーサーの検証のみ)に対するドキュメントの検証、文字参照の解決、CDATAセクションの理解などが含まれます。XMLパーサーは、まさにそのような「ヘルパー」プログラムであり、これらすべての仕事を行います。XMLパーサーを使用すると、これらの多くの複雑さから保護され、パーサーによって実装されたAPIを介して高レベルでのプログラミングに集中できるため、プログラミング効率を上げることができます。

SAXとDOMのどちらが良いですか?

SAXとDOMの両方のパーサーには、長所と短所があります。どちらが良いかは、アプリケーションの特性によって異なります(以下の質問を参照してください)。

DOMパーサーとSAXパーサーのどちらが速度を向上させることができますか?

SAXパーサーを使用すると、速度が向上します。

ツリーベースのAPIとイベントベースのAPIの違いは何ですか?

ツリーベースのAPIは、ツリー構造を中心に配置されているため、Documentインターフェース、Nodeインターフェース、NodeListインターフェース、Elementインターフェース、Attrインターフェースなど、DOMコンポーネントであるツリーのコンポーネントにインターフェースを提供します。ただし、対照的に、イベントベースのAPIはハンドラーのインターフェイスを提供します。ContentHandlerインターフェース、DTDHandlerインターフェース、EntityResolverインターフェース、ErrorHandlerインターフェースの4つのハンドラーインターフェースがあります。

DOMパーサーとSAXパーサーの違いは何ですか?

DOMパーサーとSAXパーサーは異なる方法で機能します。

  • DOMパーサーは、入力ドキュメントからメモリ内にツリー構造を作成し、クライアントからの要求を待ちます。ただし、SAXパーサーは内部構造を作成しません。代わりに、入力ドキュメントのコンポーネントの発生をイベントとして受け取り、入力ドキュメントを読み取るときに何を読み取るかをクライアントに通知します。あ

  • DOMパーサーは、クライアントが実際にどれだけ必要とするかに関係なく、常にドキュメント全体をクライアントアプリケーションに提供します。しかし、SAXパーサーは常にクライアントアプリケーションに常にドキュメントの一部のみを提供します。

  • DOMパーサーでは、クライアントアプリケーションのメソッド呼び出しは明示的である必要があり、一種のチェーンを形成します。しかし、SAXでは、特定のイベントが発生したときに「コールバック」と呼ばれる方法で(通常は科学者によってオーバーライドされる)一部の特定のメソッドが自動的に(暗黙的に)呼び出されます。これらのメソッドは明示的に呼び出すこともできますが、クライアントから明示的に呼び出す必要はありません。

どのパーサーが優れているかをどのように判断するのですか?

理想的には、優れたパーサーは高速(時間効率が良い)、スペース効率がよく、機能が豊富で使いやすいものでなければなりません。しかし、実際には、主要なパーサーのいずれも、これらすべての機能を同時に備えていません。たとえば、DOMパーサーは機能が豊富です(メモリ内にDOMツリーを作成し、ドキュメントの任意の部分に繰り返しアクセスしてDOMツリーを変更できるため)が、ドキュメントが巨大な場合はスペース効率が悪い、それを扱う方法を学ぶのに少し時間がかかります。ただし、大きな入力ドキュメントの場合、SAXパーサーはスペース効率がはるかに高くなります(内部構造を作成しないため)。さらに、APIは非常にシンプルであるため、DOMパーサーよりも実行速度が速く、学習も容易です。しかし、機能の観点からは、提供する機能が少ないため、独自のデータ構造を作成するなど、ユーザー自身がより多くのことを処理する必要があります。ところで、良いパーサーとは何ですか?答えは実際にはアプリケーションの特性に依存すると思います。

DOMパーサーを使用するよりもSAXパーサーを使用する方が有利な実際のアプリケーションとは何ですか?DOMパーサーとSAXパーサーの通常のアプリケーションは何ですか?

次の場合、DOMパーサーを使用するよりもSAXパーサーを使用する方が有利です。

  • 入力ドキュメントが利用可能なメモリには大きすぎます(実際には、この場合はSAXが唯一の選択肢です)
  • 連続した小さな入力チャンクでドキュメントを処理できます。有用な作業を行う前にドキュメント全体を必要としない
  • パーサーを使用して目的の情報を抽出するだけで、すべての計算は完全に自分で作成したデータ構造に基づいて行われます。実際、ほとんどのアプリケーションでは、DOMツリーほど複雑ではない独自のデータ構造を作成しています。この意味から、DOMパーサーを使用する可能性はSAXパーサーを使用する可能性よりも低いと思います。

以下の場合、DOMパーサーを使用する方がSAXパーサーを使用するよりも有利です。

  • アプリケーションは、ドキュメントの広く個別の部分に同時にアクセスする必要があります。
  • アプリケーションでは、ドキュメント自体と同じくらい複雑な内部データ構造を使用している可能性があります。
  • アプリケーションはドキュメントを繰り返し変更する必要があります。
  • アプリケーションは、多くのメソッド呼び出しを通じてかなりの時間ドキュメントを保存する必要があります。

例(DOMパーサーまたはSAXパーサーを使用しますか?):

講師が生徒のすべての個人情報とクラスで生徒が作成したポイントを含むXMLドキュメントがあり、アプリケーションを使用して生徒に最終成績を割り当てているとします。彼が作成したいのは、SSNとグレードのリストです。また、彼のアプリケーションでは、インストラクターは学生の個人情報とポイントを格納するために配列などのデータ構造を使用しないと想定しています。インストラクターがクラス平均以上のクラスを獲得した人にAを、他の人にBを与えることを決定した場合、彼のアプリケーションではDOMパーサーを使用することをお勧めします。その理由は、ドキュメント全体が処理される前のクラス平均がどれだけあるかを知る方法がないためです。彼が自分のアプリケーションでおそらく行う必要があるのは、最初にすべての学生の ポイントを計算して平均を計算し、ドキュメントをもう一度調べて、生徒が獲得したポイントをクラスの平均と比較して、各生徒に最終成績を割り当てます。ただし、インストラクターが90点以上を獲得した学生にAを割り当て、他の学生にBを割り当てるようなグレーディングポリシーを採用している場合は、SAXパーサーを使用することをお勧めします。その理由は、各生徒に最終成績を割り当てるために、ドキュメント全体が処理されるのを待つ必要がないためです。SAXパーサーがこの生徒の成績を読み取ったら、すぐに生徒に成績を割り当てることができます。上記の分析では、インストラクターが自分のデータ構造を作成していないと想定しました。SSNを格納するための文字列の配列や、ポイントを復元するための整数の配列など、独自のデータ構造を作成した場合はどうなるでしょうか。この場合、メモリと時間の両方を節約しながら作業を完了する前に、SAXの方が良い選択だと思います。さて、この例についてもう1つ検討します。講師がリストを印刷するのではなく、各生徒の成績を更新して元のドキュメントを保存する場合はどうなりますか?この場合、DOMパーサーは、採用しているグレーディングポリシーに関係なく、より適切な選択肢になるはずです。彼は自分のデータ構造を作成する必要はありません。彼がする必要があるのは、最初にDOMツリーを変更(つまり、値を「グレード」ノードに設定)してから、変更したツリー全体を保存することです。DOMパーサーの代わりにSAXパーサーを使用することを選択した場合、この場合、仕事を完了する前に、DOMツリーと同じくらい複雑なデータ構造を作成する必要があります。まだ仕事を成し遂げる。さて、この例についてもう1つ検討します。講師がリストを印刷するのではなく、各生徒の成績を更新して元のドキュメントを保存する場合はどうなりますか?この場合、DOMパーサーは、採用しているグレーディングポリシーに関係なく、より適切な選択肢になるはずです。彼は自分のデータ構造を作成する必要はありません。彼がする必要があるのは、最初にDOMツリーを変更(つまり、値を「グレード」ノードに設定)してから、変更したツリー全体を保存することです。DOMパーサーの代わりにSAXパーサーを使用することを選択した場合、この場合、仕事を完了する前に、DOMツリーと同じくらい複雑なデータ構造を作成する必要があります。まだ仕事を成し遂げる。さて、この例についてもう1つ検討します。講師がリストを印刷するのではなく、各生徒の成績を更新して元のドキュメントを保存する場合はどうなりますか?この場合、DOMパーサーは、採用しているグレーディングポリシーに関係なく、より適切な選択肢になるはずです。彼は自分のデータ構造を作成する必要はありません。彼がする必要があるのは、最初にDOMツリーを変更(つまり、値を「グレード」ノードに設定)してから、変更したツリー全体を保存することです。DOMパーサーの代わりにSAXパーサーを使用することを選択した場合、この場合、仕事を完了する前に、DOMツリーと同じくらい複雑なデータ構造を作成する必要があります。しかし、各生徒の成績を更新して元のドキュメントを保存するには?この場合、DOMパーサーは、採用しているグレーディングポリシーに関係なく、より適切な選択肢になるはずです。彼は自分のデータ構造を作成する必要はありません。彼がする必要があるのは、最初にDOMツリーを変更(つまり、値を「グレード」ノードに設定)してから、変更したツリー全体を保存することです。DOMパーサーの代わりにSAXパーサーを使用することを選択した場合、この場合、仕事を完了する前に、DOMツリーと同じくらい複雑なデータ構造を作成する必要があります。しかし、各生徒の成績を更新して元のドキュメントを保存するには?この場合、DOMパーサーは、採用しているグレーディングポリシーに関係なく、より適切な選択肢になるはずです。彼は自分のデータ構造を作成する必要はありません。彼がする必要があるのは、最初にDOMツリーを変更(つまり、値を「グレード」ノードに設定)してから、変更したツリー全体を保存することです。DOMパーサーの代わりにSAXパーサーを使用することを選択した場合、この場合、仕事を完了する前に、DOMツリーと同じくらい複雑なデータ構造を作成する必要があります。ノード)、変更されたツリー全体を保存します。DOMパーサーの代わりにSAXパーサーを使用することを選択した場合、この場合、仕事を完了する前に、DOMツリーと同じくらい複雑なデータ構造を作成する必要があります。ノード)、変更されたツリー全体を保存します。DOMパーサーの代わりにSAXパーサーを使用することを選択した場合、この場合、仕事を完了する前に、DOMツリーと同じくらい複雑なデータ構造を作成する必要があります。

問題の説明:指定されたXMLドキュメントの要素であるサークルに関するすべての情報を抽出するJavaプログラムを記述します。各円要素には3つの子要素(つまり、x、y、および半径)と色属性があると仮定します。サンプルドキュメントを以下に示します。

<?xml version="1.0"?> 
<!DOCTYPE shapes [
<!ELEMENT shapes (circle)*>
<!ELEMENT circle (x,y,radius)>
<!ELEMENT x (#PCDATA)>
<!ELEMENT y (#PCDATA)>
<!ELEMENT radius (#PCDATA)>
<!ATTLIST circle color CDATA #IMPLIED>
]>

<shapes> 
          <circle color="BLUE"> 
                <x>20</x>
                <y>20</y>
                <radius>20</radius> 
          </circle>
          <circle color="RED" >
                <x>40</x>
                <y>40</y>
                <radius>20</radius> 
          </circle>
</shapes> 

DOMparserを使用したプログラム

import java.io.*;
import org.w3c.dom.*;
import org.apache.xerces.parsers.DOMParser;


public class shapes_DOM {
   static int numberOfCircles = 0;   // total number of circles seen
   static int x[] = new int[1000];   // X-coordinates of the centers
   static int y[] = new int[1000];   // Y-coordinates of the centers  
   static int r[] = new int[1000];   // radius of the circle
   static String color[] = new String[1000];  // colors of the circles 

   public static void main(String[] args) {   

      try{
         // create a DOMParser
         DOMParser parser=new DOMParser();
         parser.parse(args[0]);

         // get the DOM Document object
         Document doc=parser.getDocument();

         // get all the circle nodes
         NodeList nodelist = doc.getElementsByTagName("circle");
         numberOfCircles =  nodelist.getLength();

         // retrieve all info about the circles
         for(int i=0; i<nodelist.getLength(); i++) {

            // get one circle node
            Node node = nodelist.item(i);

            // get the color attribute 
            NamedNodeMap attrs = node.getAttributes();
            if(attrs.getLength() > 0)
               color[i]=(String)attrs.getNamedItem("color").getNodeValue();

            // get the child nodes of a circle node 
            NodeList childnodelist = node.getChildNodes();

            // get the x and y value 
            for(int j=0; j<childnodelist.getLength(); j++) {
               Node childnode = childnodelist.item(j);
               Node textnode = childnode.getFirstChild();//the only text node
               String childnodename=childnode.getNodeName(); 
               if(childnodename.equals("x")) 
                  x[i]= Integer.parseInt(textnode.getNodeValue().trim());
               else if(childnodename.equals("y")) 
                  y[i]= Integer.parseInt(textnode.getNodeValue().trim());
               else if(childnodename.equals("radius")) 
                  r[i]= Integer.parseInt(textnode.getNodeValue().trim());
            }

         }

         // print the result
         System.out.println("circles="+numberOfCircles);
         for(int i=0;i<numberOfCircles;i++) {
             String line="";
             line=line+"(x="+x[i]+",y="+y[i]+",r="+r[i]+",color="+color[i]+")";
             System.out.println(line);
         }

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

    }

}

SAXparserを使用したプログラム

import java.io.*;
import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;
import org.apache.xerces.parsers.SAXParser;


public class shapes_SAX extends DefaultHandler {

   static int numberOfCircles = 0;   // total number of circles seen
   static int x[] = new int[1000];   // X-coordinates of the centers
   static int y[] = new int[1000];   // Y-coordinates of the centers
   static int r[] = new int[1000];   // radius of the circle
   static String color[] = new String[1000];  // colors of the circles

   static int flagX=0;    //to remember what element has occurred
   static int flagY=0;    //to remember what element has occurred
   static int flagR=0;    //to remember what element has occurred

   // main method 
   public static void main(String[] args) {   
      try{
         shapes_SAX SAXHandler = new shapes_SAX (); // an instance of this class
         SAXParser parser=new SAXParser();          // create a SAXParser object 
         parser.setContentHandler(SAXHandler);      // register with the ContentHandler 
         parser.parse(args[0]);
      }  catch (Exception e) {e.printStackTrace(System.err);}  // catch exeptions
   }

   // override the startElement() method
   public void startElement(String uri, String localName, 
                       String rawName, Attributes attributes) {
         if(rawName.equals("circle"))                      // if a circle element is seen
            color[numberOfCircles]=attributes.getValue("color");  // get the color attribute 

         else if(rawName.equals("x"))      // if a x element is seen set the flag as 1 
            flagX=1;
         else if(rawName.equals("y"))      // if a y element is seen set the flag as 2
            flagY=1;
         else if(rawName.equals("radius")) // if a radius element is seen set the flag as 3 
            flagR=1;
   }

   // override the endElement() method
   public void endElement(String uri, String localName, String rawName) {
         // in this example we do not need to do anything else here
         if(rawName.equals("circle"))                       // if a circle element is ended 
            numberOfCircles +=  1;                          // increment the counter 
   }

   // override the characters() method
   public void characters(char characters[], int start, int length) {
         String characterData = 
             (new String(characters,start,length)).trim(); // get the text

         if(flagX==1) {        // indicate this text is for <x> element 
             x[numberOfCircles] = Integer.parseInt(characterData);
             flagX=0;
         }
         else if(flagY==1) {  // indicate this text is for <y> element 
             y[numberOfCircles] = Integer.parseInt(characterData);
             flagY=0;
         }
         else if(flagR==1) {  // indicate this text is for <radius> element 
             r[numberOfCircles] = Integer.parseInt(characterData);
             flagR=0;
         }
   }

   // override the endDocument() method
   public void endDocument() {
         // when the end of document is seen, just print the circle info 
         System.out.println("circles="+numberOfCircles);
         for(int i=0;i<numberOfCircles;i++) {
             String line="";
             line=line+"(x="+x[i]+",y="+y[i]+",r="+r[i]+",color="+color[i]+")";
             System.out.println(line);
         }
   }


}

6

実際には:book.xml

<bookstore>
  <book category="cooking">
    <title lang="en">Everyday Italian</title>
    <author>Giada De Laurentiis</author>
    <year>2005</year>
    <price>30.00</price>
  </book>
</bookstore>
  • DOMは、メモリ内で次のツリー構造としてxmlドキュメントを提示します。
  • DOMはW3C標準です。
  • DOMパーサーはドキュメントオブジェクトモデルで動作します。
  • DOMはより多くのメモリを占有し、小さなXMLドキュメントに適しています
  • DOMは、順方向または逆方向に簡単にナビゲートできます。

ここに画像の説明を入力してください


  • SAXは、として、XML文書を提示ベースのイベントのようにstart element:abcend element:abc
  • SAXはW3C標準ではなく、開発者グループによって開発されました。
  • SAXはメモリを使用しないため、大きなXMLドキュメントに適しています。
  • 文書を順次処理するため、後方ナビゲーションはできません。
  • イベントはノード/要素に発生し、すべてのサブノードを提供します(ラテン語の結節、「ノット」)。

このXMLドキュメントは、SAXパーサーに渡されると、次のような一連のイベントを生成します

start element: bookstore
start element: book with an attribute category equal to cooking
start element: title with an attribute lang equal to en
Text node, with data equal to Everyday Italian
....
end element: title
.....
end element: book
end element: bookstore

なぜDOM解析の視覚的表現がattr: "lang"element: <title>にあるのですか?XMLを見ると、それは次のようになりattr、そのに対して平行であるべき<element>などと<book>category。それは単にスペースを節約するテクニックですか、それとも意図された親子関係がありますか?
1252748

スペースを節約するための手法
Premraj

3

DOMはDocument Object Modelの略で、各要素がツリーを分岐するツリー形式にXMLドキュメントを表します。DOMパーサーは、XMLファイルのメモリ内ツリー表現を作成してから解析するため、Java.lang.OutOfMemoryError:java heap spaceを回避するために、より多くのメモリが必要であり、DOMパーサーのヒープサイズを増やすことをお勧めします。DOMパーサーを使用したXMLファイルの解析は、XMLファイルが小さい場合は非常に高速ですが、DOMパーサーを使用して大きなXMLファイルを読み取ろうとすると、時間がかかるか、単に完全にロードできない可能性があります。 XML Dom Treeを作成するには大量のメモリが必要です。JavaはDOM解析をサポートしており、DOMパーサーを使用してJavaでXMLファイルを解析できます。DOMクラスはw3c.domパッケージにあり、DOMパーサーfor JavaはJAXP(Java API for XML Parsing)パッケージにあります。

JavaでのSAX XMLパーサー

SAXは、XML解析用のシンプルなAPIの略です。これはイベントベースのXML解析であり、XMLファイルを段階的に解析するので、大きなXMLファイルに適しています。SAX XMLパーサーは、開始タグ、要素、または属性を検出するとイベントを発生させ、それに応じて解析が機能します。SAX XMLパーサーを使用してJavaで大きなxmlファイルを解析することをお勧めします。JavaでXMLファイル全体をロードする必要がなく、大きなXMLファイルを小さな部分で読み取ることができるためです。JavaはSAXパーサーのサポートを提供し、SAXパーサーを使用してJavaで任意のxmlファイルを解析できます。ここでは、SAXパーサーを使用してxmlファイルを読み取る例を取り上げました。JavaでSAXパーサーを使用することの1つの欠点は、SAXパーサーを使用してJavaでXMLファイルを読み取ると、DOMパーサーと比較してより多くのコードが必要になることです。

DOMとSAX XMLパーサーの違い

JavaでのDOMパーサーとSAXパーサーのいくつかの高レベルの違いは次のとおりです。

1)DOMパーサーはxmlドキュメント全体をメモリにロードしますが、SAXはXMLファイルの小さな部分のみをメモリにロードします。

2)DOMパーサーはメモリ内のXMLドキュメント全体にアクセスするため、SAXよりも高速です。

3)JavaのSAXパーサーは、多くのメモリを必要としないため、DOMパーサーよりも大きなXMLファイルに適しています。

4)DOMパーサーはドキュメントオブジェクトモデルで機能し、SAXはイベントベースのxmlパーサーです。

詳細:http : //javarevisited.blogspot.com/2011/12/difference-between-dom-and-sax-parsers.html#ixzz2uz1bJQqZ


2

SAXとDOMの両方を使用して、XMLドキュメントを解析します。どちらにも長所と短所があり、状況に応じてプログラミングで使用できます

サックス:

  1. ノードごとに解析

  2. XMLをメモリに保存しません

  3. ノードを挿入または削除できません

  4. 上から下へのトラバース

DOM

  1. 処理する前に、XMLドキュメント全体をメモリに格納します

  2. より多くのメモリを占有します

  3. ノードを挿入または削除できます

  4. 任意の方向にトラバースします。

ノードを見つける必要があり、挿入または削除する必要がない場合は、SAX自体を使用できます。そうでない場合は、より多くのメモリがあればDOMを使用できます。


1

1)DOMパーサーはXMLドキュメント全体をメモリにロードしますが、SAXはXMLファイルのごく一部をメモリにロードします。

2)DOMパーサーはメモリ内のXMLドキュメント全体にアクセスするため、SAXよりも高速です。

3)JavaのSAXパーサーは、多くのメモリを必要としないため、DOMパーサーよりも大きなXMLファイルに適しています。

4)DOMパーサーはドキュメントオブジェクトモデルで機能し、SAXはイベントベースのXMLパーサーです。

詳細:http : //javarevisited.blogspot.com/2011/12/difference-between-dom-and-sax-parsers.html#ixzz498y3vPFR

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.