概要: eXtensible Markup Language (XML) は業界で急速に使用されており、プラットフォーム、言語、プロトコルに依存しない形式でデータを記述および交換するための標準として広く使用されています。 XML とその補助仕様は、データのドキュメント表現の記述、XML ドキュメント タイプの制限の記述、XML ドキュメントとリソース間のリンクの記述、および XML ドキュメントの自動変換とフォーマット設定の記述に使用できます。
カスタム タグ ライブラリを開発するにはどうすればよいですか?
私は長い間、JSP と ASP プログラミングを使用してきましたが、サーバー側の 2 つのプログラミング方法のうち、JSP の方がはるかに強力であると感じています。言うまでもなく、私がサーバーサイド Web アプリケーション開発ツールとして JSP を選択する理由は、JSP のタグ ライブラリにあります。なぜ?理由: メンテナンスと開発のスピード。単一のサーバー ページ内で、さまざまなスクリプト メソッドとオブジェクトを組み合わせて使用できます。 「コンクリート」と同様に、この組み合わせによりサーバー側のスクリプトが強力になり、サーバー側プログラマが非常に柔軟で動的な Web ページを設計できるようになります。ただし、この自由な組み合わせには、保守が非常に面倒であるという欠点もあります。特にプロジェクトが大きくなると、最終製品は従来の Web デザイナーによって保守されるため、さらに悪いことに、コードの複雑さが増すにつれて開発速度が遅くなり、メディアやコンテンツの開発には役に立ちません。大規模な Web アプリケーションを開発した後も、サイトではこれらのかなり複雑なコードを保守する資格のあるプログラマーを見つける必要があります。
幸いなことに、JSP は優れたソリューションを提供します。タグ ライブラリは、再利用可能なコード ブロックを構築する簡単な方法を提供します。タグ ライブラリを設計すると、多くのプロジェクトで再度使用できます。さらに便利なのは、COM や J2EE とは異なり、タグ ライブラリを作成するために他のスキルを学ぶ必要がないことです。 JSP の記述方法を知っていれば、タグ ライブラリを作成できます。タグ ライブラリにより、Web アプリケーションのメンテナンスも改善できます。これは、JSP ページのカスタム タグを使用した単純な XML インターフェイスです。このようにして、Web デザイナーは、JSP の知識がなくても JSP Web アプリケーションを構築できます。このオープンなWeb開発はチーム運営に非常に効果的です。 JSP プログラマはカスタム タグとバックグラウンド コード モジュールを作成でき、Web デザイナーはカスタム タグを使用して Web アプリケーションを構築し、Web デザインに集中できます。
1. タグライブラリの定義 JSP タグライブラリ (カスタムライブラリとも呼ばれます) は、JavaBeans でサポートされている XML ベースのスクリプトを生成するためのメソッドのセットとみなすことができます。概念的には、タグ ライブラリは非常にシンプルで再利用可能なコード構造です。
XML/XSL 変換を実行するタグの例と HTML ページ
<%@ taglib uri=" http://www.jspinsider.com/jspkit/JAXP " prefix="JAXP"%>
c:/xml/example.xml
c:/xml/example.xsl
この例では、単純なタグを使用してバックグラウンドでより強力なコードにアクセスすることにより、XML がロードされ、XSL ファイルを通じて結果が生成され、クライアントに送信されます。単純なタグ呼び出しを使用します。
カスタム タグは、JSP プロジェクトで簡単に再利用可能なコードを作成するための扉を開きます。必要なのは、タグ ライブラリとそのドキュメントだけです。
2. タグ コンポーネント タグ ライブラリは非常に使いやすいですが、タグ ライブラリをサポートする内部設計を作成するのは非常に複雑で、少なくとも単純な JavaBean を作成するよりも複雑です。この複雑さは、タグ ライブラリが複数の部分で構成されているという事実に起因します。ただし、必要なのは Java と JSP だけです。
単純なタグは次の要素で構成されます。
⑴ JavaBeans: Java 固有のオブジェクト指向の利点を得るには、再利用可能なコードを独立したコード コンテナーに配置する必要があります。これらの JavaBean はタグ ライブラリの一部ではありません。ただし、これはコード ベースが関連タスクを実行するために使用するコードの基本ブロックです。
⑵ タグ処理: これがタグ ライブラリの真のコアです。タグ ハンドラーは、必要なリソース (JavaBeans) を参照し、JSP ページに関するすべての情報 (pageContext オブジェクト) にアクセスします。また、JSP ページは、設定されているすべてのタグ属性と、JSP ページ上のタグ本体の内容をタグ プロセッサに送信します。タグ プロセッサは処理を完了すると、処理のために出力を JSP ページに送り返します。
⑶ タグライブラリ記述(tldファイル):タグプロセッサの属性、情報、位置を記録する単純なXMLファイルです。 JSP コンテナはこのファイルを使用して、タグ ライブラリを呼び出す場所と方法を認識します。
⑷ Web サイトの web.xml ファイル: これは Web サイトの初期化ファイルです。このファイルでは、Web サイトで使用されるカスタム タグと、各カスタム タグを記述するために使用される tld ファイルを定義します。
⑸ 配布ファイル (WAR または JAR ファイル): カスタム タグを再利用したい場合は、それをあるプロジェクトから別のプロジェクトに転送する方法が必要です。タグ ライブラリを JAR ファイルにパッケージ化するのは、簡単で効果的な方法です。
⑹ JSP ファイル内でタグ ライブラリの宣言を作成します。このタグを使用する場合は、ページ上で宣言するだけで済みます。その後は、JSP ページのどこでも使用できます。
やるべきことがたくさんあるように思えますが、実際はそれほど難しいことではありません。重要なのはコーディングではなく、断片を正しく整理することです。ただし、この階層化によりラベルの使用が柔軟になり、転送が容易になるため、この階層化は重要です。さらに重要なのは、これらのレイヤーは、JSP IDE (JSP 統合開発環境) を介してタグを作成するプロセスを自動化するために存在することです。将来の JSP IDE では、カスタム タグの作成作業のほとんどが自動的に完了するため、コードを記述してタグ処理を行うだけで済むようになることが期待されています。
注: タグ ハンドラーはカスタム タグを 1 つだけ定義します。タグ ライブラリは、同じタスクを処理する複数のタグ プロセッサのコレクションです。
3. 独自のタグを作成します。以下では、独自の HTML エンコード機能を備えた JSP を拡張してカスタム タグを作成する方法を段階的に説明します。この機能は、すべての < および > 文字を HTML コードに置き換えます。他のエンコード処理を実行するために簡単に拡張できます。わかりやすくするために、この例ではカスタム タグ作成の基本要素のみを説明します。
⑴ JavaBeanを作成する
コードの再利用可能な部分はすべて JavaBean に配置する必要があります。このコードはプロジェクト内の他の場所で頻繁に使用されるため、これは重要です。タグ ハンドラー内に配置されたコードはタグの外部では再利用できないため、再利用可能なコード部分を分離することが重要です。この例では、HTML 用にコーディングされたロジックは共通であるため、JavaBean に配置されます。
⑵ HTMLエンコーディング JavaBean
/* HTML_Format.Java */
public class HTML_Format extends Objectimplements Java.io.Serializable {
/** 新しい HTML_Format を作成します */
パブリック HTML_Format() {}
/** 文字列内のすべての < および > 文字を応答の HTML エンコーディングに置き換えます */
public String HTML_Encode(String as_data)
{
int li_len = as_data.length();
/*文字列バッファの長さが元の文字列より長い*/
StringBuffer lsb_encode = new StringBuffer(li_len + (li_len/10));
/* ループしてすべての < および > 文字を置き換えます*/
for(int li_count = 0; li_count < li_len; li_count++)
{ String ls_next = String.valueOf(as_data.charAt(li_count));
if (ls_next.equals("<")) ls_next = "<";
if (ls_next.equals(">")) ls_next = ">";
lsb_encode.append(ls_next);
}
return(lsb_encode.toString());
}
⑶
タグ プロセッサを作成します。タグ プロセッサは次のコードを使用します。
HTML エンコード タグ プロセッサ
Java.io.IOExceptionをインポートします。
Javax.servlet.jsp.* をインポートします。
import Javax.servlet.jsp.tagext.*;
パブリック クラス HTML_FormatTag は BodyTagSupport を拡張します
{
/* 1} この関数はタグの最後で呼び出されます*/
public int doEndTag() は JspTagException をスローします
{
試す
{ /* 2} ラベル内のテキストを取得します */
ボディコンテンツ l_tagbody = getBodyContent();
文字列 ls_output = "";
/* 3} タグ本体にテキストが含まれている場合は、それを処理します */
if(l_tagbody != null)
{ HTML_Format l_format = 新しい HTML_Format();
/* 3a} タグ本体の内容を文字列に変換します */
文字列 ls_html_text = l_tagbody.getString();
ls_output = l_format.HTML_Encode(ls_html_text);
}
/* 4}結果をデータ ストリームに書き戻します*/
pageContext.getOut().write(ls_output.trim());
}
catch (IOException e)
{ throw new JspTagException("タグ エラー:" + e.toString());
}
/* JSP に後続のページのコンテンツの処理を継続させます*/
EVAL_PAGEを返します;
}
この処理は非常に単純で、次のものが含まれます
。
o タグの先頭と末尾の間のテキストを読み取ります。 o html エンコード関数を呼び出します。 o 結果を JSP ページに返します。
⑷ タグ記述子の作成では、システムが処理方法を認識できるようにカスタム タグを記述する必要があります。この記述ファイルのサフィックスは .tld で、通常、その名前はタグ プロセッサと同じで、「/WEB-INF/」ディレクトリに保存されます。
HTMLエンコードタグ記述子
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP タグ ライブラリ 1.1//EN"
「 http://Java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd 」
<タグリブ>
<タグ>
タグ>
⑸ Web XML ファイルを更新して、JSP コンテナにタグ ライブラリを使用するように指示します。これを行うには、web.xml ファイルを変更する必要があります。具体的には、taglib プロジェクトを追加してタグ ライブラリを登録する必要があります。最も重要なのは、タグに URI を割り当てることです。 URI は、Web サイト上のこの特定のタグにのみ適用される一意の参照です。タグはさまざまな Web サイトで使用できるため、一意性を確保するために完全な URL またはパッケージ名を使用することをお勧めします。この例は簡略化されています。
web.xmlファイルを変更する
PUBLIC "-//Sun Microsystems, Inc.//DTD Web アプリケーション 2.2//EN"
「 http://Java.sun.com/j2ee/dtds/web-app_2.2.dtd 」
<タグリブ>
<タグリブウリ>
HTMLエンコード
<タグリブの場所>
/WEB-INF/HTML_FormatTag.tld
タグリブ>
⑹ 新しいタグを使用したカスタムタグが設定され、JSP ページで使用できるようになります。これを行うには、taglib ディレクティブを使用してページ上でタグを宣言するだけです。タグはその固有の URI によって参照され、名前空間プレフィックスが割り当てられます。他の名前空間と競合しない限り、プレフィックスは任意です。
JSP ページで HTML エンコード タグを使用します:
<%@ taglib uri="HTMLEncode" prefix="Examples" %>
<プレ>
<例:HTMLEncode>
<こんにちは、簡単なサンプル>
例:HTMLエンコード>
サンプルコードの出力
<こんにちは、簡単なサンプル>
これは次のように表示されます。
<こんにちは、簡単なサンプル>
このタグを使用して、ページのすべてのコードをエンコードしました。興味深いのは、すべてのカスタム タグがサーバー上で処理されることです。これは、出力ページにカスタム タグが表示されないことを意味します。
ラベルを作成するのは難しくありません。最も難しいのは、ラベル処理の詳細をすべて学ぶことです。これは非常に強力な機能ですが、ここでは基本についてのみ触れました。このプロセスにはいくつかの手順が必要なため、新しい JSP プログラマはタグを作成するときに混乱するでしょう。
JSP を使用して DOM アプリケーションを開発するにはどうすればよいですか?
DOMとはDocument Object Modelの略で、ドキュメントオブジェクトモデルのことです。 XML はデータをツリーに編成するため、DOM はこのツリーのオブジェクト記述です。平たく言えば、XML 文書を解析して XML 文書のツリー モデルを論理的に構築することであり、ツリーのノードがオブジェクトです。これらのオブジェクトにアクセスすることで、XML ドキュメントのコンテンツにアクセスできます。
以下の簡単な例を見て、DOM で XML ドキュメントを操作する方法を見てみましょう。これは XML ドキュメントであり、操作対象のオブジェクトです:
<メッセージ>
JAXP
を使用して、このドキュメントのコンテンツを Java オブジェクトに解析する必要があります。これは、わずか数行のコードで実行できます。まず、パーサー ファクトリを作成し、このファクトリを使用して特定のパーサー オブジェクトを取得する必要があります。
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
ここで DocumentBuilderFacotry を使用する目的は、特定のパーサーから独立したプログラムを作成することです。DocumentBuilderFactory クラスの静的メソッド newInstance() が呼び出されるときに、システム変数に基づいてどのパーサーを使用するかを決定します。また、すべてのパーサーは JAXP によって定義されたインターフェースに従うため、どのパーサーが使用されてもコードは同じになります。したがって、異なるパーサー間で切り替える場合は、コードを変更せずにシステム変数の値を変更するだけで済みます。これが工場のメリットです。
DocumentBuilder db = dbf.newDocumentBuilder();
ファクトリ オブジェクトを取得した後、その静的メソッド newDocumentBuilder() メソッドを使用して、特定の DOM パーサーを表す DocumentBuilder オブジェクトを取得します。ただし、Microsoft 製か IBM 製のどちらのパーサーであるかは、プログラムにとって重要ではありません。
次に、このパーサーを使用して XML ドキュメントを解析できます。
ドキュメント doc = db.parse("c:/xml/message.xml");
DocumentBuilder の parse() メソッドは、XML ドキュメント名を入力パラメータとして受け取り、Document オブジェクトを返します。この Document オブジェクトは、XML ドキュメントのツリー モデルを表します。 XML ドキュメントに対する今後のすべての操作はパーサーとは何の関係もなく、この Document オブジェクトに対して直接操作できます。 Document を操作する具体的な方法は DOM によって定義されます。
取得した Document オブジェクトから DOM の旅を始めることができます。 Document オブジェクトの getElementsByTagName() メソッドを使用すると、NodeList オブジェクトを取得できます。Node オブジェクトは XML ドキュメント内のタグ要素を表し、NodeList オブジェクトはその名前からわかるように、Node オブジェクトを表します。
NodeList nl = doc.getElementsByTagName("メッセージ");
このようなステートメントを通じて取得するのは、XML ドキュメント内のすべての
ノード my_node = nl.item(0);
Node オブジェクトが作成されると、XML ドキュメントに格納されているデータが抽出され、Node にカプセル化されます。この例では、Message タグ内のコンテンツを抽出するために、通常、Node オブジェクトの getNodeValue() メソッドを使用します。
文字列メッセージ = my_node.getFirstChild().getNodeValue();
ここでは、メッセージの下の最初の子 Node オブジェクトを取得するために getFirstChild() メソッドも使用されていることに注意してください。メッセージ タグの下にはテキスト以外のサブタグや属性はありませんが、ここでは主に W3C の DOM 定義に関連する getFirseChild() メソッドを使用することを主張します。 W3C ではタグ内のテキスト部分も Node として定義しているため、 getNodeValue() を使用してテキストの内容を取得する前に、まずテキストを表す Node を取得する必要があります。 XML ファイルからデータを抽出できたので、このデータを適切な場所で使用してアプリケーションを構築できます。
DOM の例
まず、この例が何を行うかについて説明します。追加された URL アドレスは、この XML ファイルに書き込まれます。これは非常にシンプルですが非常に実用的で、DOM の使用法のほとんどを説明するには十分です。
最初のプログラムは xmldisplay.Java と呼ばれ、その主な機能は、この XML ファイル内の各ノードの内容を読み取り、System.out で出力をフォーマットすることです。このプログラムを見てみましょう:
import Javax.xml.parsers。 *;
import org.w3c.dom.*;
これは必要なクラスを導入するためのもので、ここでは Sun が提供する XML パーサーを使用するため、DOM パーサーと SAX 解析を含む Java.xml.parsers パッケージを導入する必要があります。デバイスの特定の実装。 org.w3c.dom パッケージは、w3c によって開発された DOM インターフェイスを定義します。
DocumentBuilderFactory ファクトリ = DocumentBuilderFactory.newInstance();
DocumentBuilder builder=factory.newDocumentBuilder();
ドキュメント doc=builder.parse("links.xml");
doc.normalize();
上記に加えて、Document オブジェクトに対してnormalize() を呼び出すと、XML ドキュメント内の空白としてマッピングされている不要な Text Node オブジェクトを書式設定されたコンテンツとして削除できます。そうしないと、取得する DOM ツリーが想像したものと異なる可能性があります。特に出力する場合にはこのnormalize()の方が便利です。
NodeList links =doc.getElementsByTagName("link");
先ほど述べたように、XML ドキュメント内の空白文字も DOM ツリー内のオブジェクトとしてマッピングされます。したがって、Node メソッドの getChildNodes メソッドを直接呼び出すと、問題が発生し、予期した NodeList オブジェクトを返せない場合があります。解決策は、Element の getElementByTagName(String) を使用することです。返される NodeLise は予期したオブジェクトです。次に、 item() メソッドを使用して、目的の要素を抽出できます。
for (int i=0;i
System.out.print("コンテンツ: ");
System.out.println(link.getElementsByTagName("text").item(0).getFirstChild();
.getNodeValue());
...
上記のコード スニペットにより、XML ドキュメント コンテンツのフォーマットされた出力が完成します。 getFirstChile() メソッドや getElementsByTagName() メソッドの使用など、いくつかの詳細に注意すれば、これらは比較的簡単です。
以下の内容は、DOM ツリーを変更した後に XML ドキュメントに書き直すことについてです。このプログラムは xmlwrite.Java と呼ばれます。 JAXP 1.0 バージョンには、XML ドキュメントの作成を処理できる直接のクラスやメソッドがないため、他のパッケージ内のいくつかの補助クラスを使用する必要があります。 JAXP 1.1 バージョンでは、XSLT のサポートが導入されました。いわゆる XSLT は、XML 文書を変換 (変換) した後に新しい文書構造を取得することです。この新しく追加された関数を使用すると、新しく生成または変更された DOM ツリーを XML ファイルに簡単に書き戻すことができます。このコードの主な機能は、新しいリンク ノードをリンクすることです。 .xml ファイル:
Javax.xml.parsers.* をインポートします。
Javax.xml.transform.* をインポートします。
Javax.xml.transform.dom.DOMSource をインポートします。
import Javax.xml.transform.stream.StreamResult;
import org.w3c.dom.*;
新しく導入された Java.xml.transform パッケージのいくつかのクラスは、XSLT 変換を処理するために使用されます。
上記の XML ファイルに新しいリンク ノードを追加したいので、最初に links.xml ファイルを読み取り、DOM ツリーを構築し、次に DOM ツリーを変更し (ノードを追加)、最後に変更した DOM を追加する必要があります。 links.xml ファイル:
DocumentBuilderFactory ファクトリー = DocumentBuilderFactory.newInstance();
DocumentBuilder builder=factory.newDocumentBuilder();
ドキュメント doc=builder.parse("links.xml");
doc.normalize();
//---変数を取得します---
String text="漢中のホームページ";
文字列 url=" www.hzliu.com ";
文字列 author="Hzliu Liu";
String description="Hanzhong Liu のサイト、たくさんの驚きを与えてください!!!";
重要なポイントを明確に示し、手順を簡素化するために、実際にはメモリ String オブジェクトに追加するコンテンツをハードコーディングします。操作では、インターフェースを使用してユーザー入力を抽出したり、JDBC 経由でデータベースから目的のコンテンツを抽出したりすることがよくあります。
テキストテキストセグメント;
Element link=doc.createElement("link");
まず、テキスト型、属性型、要素型など、ノードの種類に関係なく、それらはすべて Document オブジェクト CreateXXX( ) メソッド (XXX は作成される特定のタイプを表します) であるため、XML ドキュメントにリンク項目を追加する必要があり、最初にリンク オブジェクトを作成します
。
textseg=doc.createTextNode(テキスト);
linktext.appendChild(textseg);
link.appendChild(リンクテキスト);
...
ノードを作成するプロセスは少し統一的かもしれませんが、注意する必要があるのは、Element に含まれるテキストです (DOM では、これらのテキストもノードを表すため、対応するノードも作成する必要があります)。これらのテキストのコンテンツを設定するには、Element オブジェクトの setNodeValue() メソッドを直接使用します。作成された Element とそのテキスト コンテンツを設定するには、作成された Text オブジェクトの setNodeValue() メソッドを使用する必要があります。 DOM ツリーに追加されます。前のコードを見ると、よりよく理解できるでしょう。
doc.getDocumentElement().appendChild(リンク);
最後に、作成したノードを DOM ツリーに追加することを忘れないでください。 Document クラスの getDocumentElement() メソッドは、ドキュメントのルート ノードを表す Element オブジェクトを返します。 XML ドキュメントでは、ルート ノードは一意である必要があります。
TransformerFactory tFactory =TransformerFactory.newInstance();
トランスフォーマー トランスフォーマー = tFactory.newTransformer();
DOMSource ソース = 新しい DOMSource(doc);
StreamResult 結果 = new StreamResult(new Java.io.File("links.xml"));
transformer.transform(source, result);
次に、XSLT を使用して DOM ツリーを出力します。ここの TransformerFactory もファクトリ パターンを適用し、特定のコードを特定のトランスフォーマーから独立させます。実装方法はDocumentBuilderFactoryと同じなのでここでは詳しく説明しません。 Transformer クラスの transfrom メソッドは、データ ソース Source と出力ターゲット Result の 2 つのパラメーターを受け入れます。ここでは DOMSource と StreamResult をそれぞれ使用するため、DOM の内容を出力ストリームに出力できます。出力ストリームがファイルの場合、DOM の内容がファイルに書き込まれます。
JSP を使用して SAX アプリケーションを開発するにはどうすればよいですか?
SAX は Simple API for XML の略称であり、W3C によって提案された正式な標準ではありません。事実上の標準と言えます。実際、これはコミュニティでの議論の成果です。それでも、SAX は DOM と同じくらい XML で使用されており、ほぼすべての XML パーサーが SAX をサポートしています。
DOM と比較して、SAX は軽量なメソッドです。 DOM を処理するときは、XML ドキュメント全体を読み取り、メモリ内に DOM ツリーを作成し、DOM ツリー上に各 Node オブジェクトを生成する必要があることがわかっています。ドキュメントが小さい場合は問題ありませんが、ドキュメントが大きくなると、DOM の処理に非常に時間と労力がかかります。特に、メモリ要件も急激に増加するため、一部のアプリケーション (アプレットなど) で DOM を使用するとコスト効率が悪くなります。現時点では、より優れた代替ソリューションは SAX です。
SAX は概念的には DOM とはまったく異なります。まず、DOM ドキュメント ドライバーとは異なり、イベント駆動型です。つまりドキュメント全体を読み取る必要がなく、ドキュメント読み取りプロセスは SAX 解析プロセスでもあります。いわゆるイベント駆動型とは、コールバック メカニズムに基づいたプログラム実行メソッドを指します。 (Java の新しいプロキシ イベント モデルについてよく理解している場合は、このメカニズムを簡単に理解できるでしょう。) XMLReader は、XML ドキュメントを受け取るプロセス、つまりドキュメントを読み取るプロセス中に、XML ドキュメントを受け取り、それを解析します。解析プロセスは同時に実行されますが、これは DOM とは大きく異なります。解析を開始する前に、ContentHandler を XMLReader に登録する必要があります。これはイベント リスナーに相当し、解析中にドキュメントが検出され始めたときに処理する内容をカスタマイズする startDocument() などの多くのメソッドが ContentHandler に定義されています。プロセスの問題。 XMLReader が適切なコンテンツを読み取ると、対応するイベントをスローし、このイベントの処理能力を ContentHandler に委任し、対応するメソッドを呼び出して応答します。
一般的に理解するのは少し難しいかもしれませんが、次の例は SAX 解析プロセスを理解するのに役立ちますので、心配しないでください。この単純な XML ファイルを見てください:
<著者>オグデン・ナッシュ著者>
XMLReader は
プロジェクト メソッド コールバック
{document start} startDocument()
が見つかりました。
"n" 文字("
「オグデン・ナッシュ」の文字("
"n" 文字("
「ノミ」文字("
"n" 文字("
「アダム」の文字("
"n" 文字("
{ドキュメントの終了} endDocument()
ContentHandler は実際にはインターフェイスであり、特定の XML ファイルを処理する場合、特定のイベントを処理するために ContentHandler を実装するクラスを作成する必要があります。これは実際には XML を処理する SAX であると言えます。文書。その中で定義されているメソッドのいくつかを見てみましょう。
voidcharacters(char[] ch, int start, int length): このメソッドは、XML ファイルで読み取られた文字列を処理するために使用されます。そのパラメータは、文字配列と、この配列内の読み取り文字列の開始位置です。長さの場合は、String クラスのコンストラクターを使用して、この文字列の String クラスを簡単に取得できます: String charEncontered=new String(ch,start,length)。
void startDocument(): ドキュメントの先頭に到達したら、このメソッドを呼び出して前処理作業を実行します。
void endDocument(): 上記のメソッドに対応して、ドキュメントが終了すると、このメソッドが呼び出され、その後の作業が行われます。
void startElement(String namespaceURI, String localName, String qName, Attributes atts): このメソッドは、開始タグが読み取られたときにトリガーされます。ネームスペースは SAX1.0 バージョンではサポートされていませんが、新しい 2.0 バージョンではネームスペースのサポートが提供されています。ここでのパラメータの namespaceURI はネームスペース、localName はラベル名、qName はラベルの変更されたプレフィックスです。名前空間を使用する場合、どちらのパラメータも null ではありません。 atts は、このタグに含まれる属性のリストです。 atts を通じて、すべての属性名と対応する値を取得できます。 SAX の重要な機能は、タグに遭遇したときに、以前に遭遇したタグを記録しないことです。つまり、startElement() メソッドでは、知っている情報はすべて名前と属性だけであることに注意してください。タグの入れ子構造、上位タグの名前、サブ要素属性の有無、その他の構造関連情報については不明であり、プログラムの助けが必要です。このため、SAX は DOM に比べてプログラミングの利便性が低くなります。
void endElement(String namespaceURI, String localName, String qName): このメソッドは、上記のメソッドに対応します。このメソッドは、終了タグが見つかったときに呼び出されます。
DOM について説明したときに使用したドキュメントの例を引き続き使用しますが、まず、XML ファイル内に各タグが出現する回数をカウントする、より単純なアプリケーションを見てみましょう。この例は非常に単純ですが、SAX プログラミングの基本的な考え方を説明するには十分です。もちろん、インポート ステートメントは
引き続き
先頭で使用されます。
Javax.xml.parsers.* をインポートします。
org.xml.sax.* をインポートします。
org.xml.sax.helpers.* をインポートします。
Java.util.* をインポートします。
import Java.io.*;
次に、DefaultHandler を継承するクラスを作成します。ここでは、プログラムの構造に注目してください。
public class SAXCounter extends DefaultHandler {
private Hashtable tags; //このハッシュテーブルは、タグの出現回数を記録するために使用されます。
//ドキュメントを処理する前の作業
public void startDocument() は SAXException をスローします {
tags = new Hashtable();//ハッシュテーブルを初期化する
}
//各開始要素の属性を処理します
public void startElement(String namespaceURI, String localName,
文字列 rawName、属性 atts)
SAXException をスローします
{
文字列キー = ローカル名;
...
このプログラムが何をするのか見てみましょう。 main() メソッドで行う主な作業は、パーサーを作成してドキュメントを解析することです。実際、ここで SAXParser オブジェクトを作成するとき、プログラム コードを特定のパーサーから独立させるために、DOM と同じ設計手法が使用されます。つまり、SAXParserFactory クラスを通じて特定の SAXParser オブジェクトを作成します。 、変更する必要があるのは環境変数の値だけであり、プログラム コードは変更しないで済みます。これがFactoryMethodパターンの考え方です。ここでは詳細は説明しませんが、それでも理解できない場合は、上記の DOM の説明を参照してください。原理は同じです。
ただし、ここで注意すべき点が 1 つあります。それは、SAXParser クラスと XMLReader クラスの関係です。少し混乱するかもしれませんが、実際、SAXParser は JAXP の XMLReader のラッパー クラスであり、XMLReader はドキュメントを解析するために SAX2.0 で定義されたインターフェイスです。 SAXParser または XMLReader の parser() メソッドを呼び出してドキュメントを解析することもでき、その効果はまったく同じです。ただし、SAXParser の parser() メソッドはより多くのパラメータを受け入れ、さまざまな XML ドキュメント データ ソースを解析できるため、XMLReader よりも使いやすいです。
この例は SAX の表面に触れているだけですが、次の例はより高度です。以下で実装したい関数は、XML ドキュメントからコンテンツを読み取って出力をフォーマットするという関数で既に実装されていますが、SAX は DOM に劣りません。
前に述べたように、startElement() メソッドで開始タグが見つかった場合、XML ドキュメント内のタグの位置を取得できません。 XML 内のタグのセマンティクスはタグの位置によって部分的に決定されるため、これは XML ドキュメントを処理する場合に大きな問題になります。また、ドキュメントの構造を検証する必要がある一部のプログラムでは、これはさらに問題になります。もちろん、スタックを使用して文書構造を記録することはできます。
スタックの特徴は先入れ先出しです。私たちの現在のアイデアは、プッシュを使用して startElemnt() メソッドでラベルの名前をスタックに追加し、それを endElement() メソッドでポップアウトすることです。適切に構造化された XML では、その入れ子構造が完全であり、各開始タグは常に終了タグに対応しており、タグの入れ子間に不整合が存在しないことがわかっています。したがって、startElement() メソッドへのすべての呼び出しは必然的に endElement() メソッドへの呼び出しに対応するため、現在のラベルがどこにあるかを簡単に知るには、スタックの構造を分析するだけで済みます。ドキュメント構造の位置。
パブリッククラスのsaxreaderはdefulthandlerを拡張します{
java.util.stack tags = new java.util.stack();
...
ここではスタック分析は使用されていませんが、実際には非常に簡単な作業ですしたがって、ベクトルクラスのサイズ()メソッドを使用してスタック内の要素の数を取得できます。各要素の属性。実際、スタックの要素を下から上に1つずつ配置すると、XMLルートノードから現在のノードの情報を使用して、ドキュメントの構造が明確になります。 。
これまでのところ、XMLプログラミングの2つの主要なツール、DomとSaxを習得し、Javaプログラムでそれらを使用する方法も知っています。 DOMプログラミングは比較的単純ですが、遅くて多くのメモリを取り上げますが、S AXプログラミングはより複雑ですが、高速でメモリが少なくなります。したがって、さまざまな環境に応じて異なる方法を使用することを選択する必要があります。ほとんどのXMLアプリケーションは基本的にそれらを使用して解決できます。 DOMとSAXは実際には言語に依存しておらず、対応する言語の実装がある限り、DOMとSAXを任意の言語で適用できる限り。