Oracle® Fusion Middleware Oracle WebLogic Server XMLアプリケーションの開発

12c (12.1.2)

E48050-01(原本部品番号:E28119-01)

目次

タイトルおよび著作権情報

はじめに

- ドキュメントのアクセシビリティについて

- 表記規則

1 概要とロードマップ

- ドキュメントの内容と対象読者

- このドキュメントの手引き

- 関連ドキュメント

- XML開発者向けのサンプル

- WebLogic Server配布キットのXMLサンプル

- このリリースでのXMLの新機能と変更点

- WebLogic ServerのXML機能の概要

- XMLドキュメント・パーサー

- WebLogic Serverバージョン8.1と9.1のデフォルト・パーサーの違い

- XMLドキュメント・トランスフォーマ

- Streaming API for XML (StAX)の実装

- WebLogic XPath API

- JAXPプラガブル・レイヤーの実装

- Java API for XML Registriesの実装

- WebLogicサーブレット属性

- WebLogic XSLT JSPタグ・ライブラリ

- パーサーおよびトランスフォーマの構成用XMLレジストリ

- 外部エンティティの解決の構成用XMLレジストリ

- 推奨規格オーバーライド機構によるDOM/SAXの切替え:サポート対象外

- XMLの詳細情報へのリンク

2 XMLの概要

- XMLとは

- XMLドキュメントの記述方法

- XMLを使用する理由

- XSLとXSLTとは

- DOMとSAXとは

- SAX

- DOM

- Streaming API for XML (StAX)とは

- JAXPとは

- JAXPパッケージ

- JAXP 1.2の新機能

- XMLとXSLTの一般的な使い方

- XMLとXSLTを使用したコンテンツと表示の分離

- 企業間通信用メッセージ・フォーマットとしてのXML

3 WebLogic Serverを使用したXMLアプリケーションの開発

- XMLアプリケーションの開発:主な手順

- XMLドキュメントの解析

- SAXモードでJAXPを使用したXMLドキュメントの解析

- DOMモードでJAXPを使用したXMLドキュメントの解析

- サーブレットでのXMLドキュメントの解析

- org.xml.sax.DefaultHandler属性を使用したドキュメントの解析

- org.w3c.dom.Document属性を使用したドキュメントの解析

- 検証パーサーと非検証パーサー

- XMLドキュメント解析時のエンティティ解決の処理

- 外部エンティティに関する一般的な情報

- WebLogic Serverのエンティティ解決機能の使用

- デフォルト・パーサー以外のパーサーの使用

- 新しいXMLドキュメントの生成

- DOMドキュメント・ツリーからのXMLの生成

- JSPでのXMLドキュメントの生成

- XMLドキュメントの変換

- JAXPによるXMLデータの変換

- JAXPによるXMLドキュメント変換の例

- JSPタグによるXMLデータの変換

- XSLT JSPタグ構文

- XSLT JSPタグの使い方

- XSLT JSPタグによるXMLドキュメントの変換

- JSPでのXSLT JSPタグの使用例

- デフォルト・トランスフォーマ以外のトランスフォーマの使い方

4 Streaming API for XML (StAX)の使い方

- Streaming API for XMLの概要

- カーソルAPIの説明

- XMLStreamReaderインタフェース

- XMLStreamWriterインタフェース

- イベント・イテレータAPIの説明

- StAXのメイン・インタフェースとクラス

- XMLStreamReaderインタフェースによるXMLの解析:一般的な手順

- StAXを使用したXML解析の例

- XMLStreamReaderオブジェクトの取得

- 特定のXMLイベント・タイプの判別

- 完全な要素名の取得

- 要素の属性の取得

- 要素のネームスペースの取得

- テキスト・データの取得

- 場所の情報の取得

- 入力ストリームのクローズ

- XMLStreamWriterインタフェースによるXMLの生成:一般的な手順

- StAXを使用したXML生成の例

- XMLStreamWriterオブジェクトの取得

- 出力ストリームへのXML宣言の追加

- 出力ストリームへの標準XMLイベントの追加

- 属性とネームスペース宣言の開始要素への追加

- 出力ストリームのクローズ

- XMLInputFactoryインタフェース用に定義されたプロパティ

- XMLOutputFactoryインタフェース用に定義されたプロパティ

5 高度なXML APIの使い方

- Java API for XML Registries (JAXR) APIの使い方

- WebLogic XPath APIの使い方

- DOMXPathクラスの使い方

- DOMXPathクラスの使用例

- DOMXPathクラスを使用する場合の主な手順

- StreamXPathクラスの使い方

- StreamXPathクラスの使用例

- StreamXPathクラスを使用する場合の主な手順

6 XMLプログラミングのベスト・プラクティス

- DOM、SAX、StAX APIを使用する場合

- XML検証のパフォーマンスの改善

- XMLスキーマまたはDTDを使用する場合

- パフォーマンスを最大にする外部エンティティ解決の構成

- SAX InputSourceの使用

- 変換のパフォーマンスの向上

7 XMLプログラミング手法

- JavaクライアントとWebLogic Serverとの間でのXMLデータの転送

- JMSアプリケーションでのXMLドキュメントの処理

- HTTPインタフェースを持たない外部エンティティへのアクセス

8 XMLアプリケーション・スコーピング

- アプリケーション・スコーピングの概要

- weblogic-application.xmlファイル

- xml

- parser-factory

- saxparser-factory

- document-builder-factory

- transformer-factory

- entity-mapping

- entity-mapping-name

- public-id

- system-id

- entity-uri

- when-to-cache

- cache-timeout-interval

- エンタープライズ・アプリケーション用のパーサーまたはトランスフォーマの構成

- エンタープライズ・アプリケーション用の外部エンティティの構成

- エンタープライズ・アプリケーション用の外部エンティティ・キャッシュの構成

9 WebLogic Server XMLの管理

- WebLogic Server XMLの管理の概要

- XMLの管理タスク

- XMLレジストリの仕組み

- XMLレジストリ内のパーサーの選択

- XMLパーサーおよびトランスフォーマの構成タスク

- デフォルト以外のパーサーまたはトランスフォーマの構成

- 特定のドキュメント・タイプに対応したパーサーの構成

- 外部エンティティの構成タスク

- 外部エンティティ解決の構成

- 外部エンティティ・キャッシュの構成

A XMLリファレンス

- XML API

- サンプル・コード

- WebLogic Serverの関連ドキュメント

- チュートリアルとオンライン・コース

- その他のXML仕様と情報

B WebLogic XML Streaming APIの使用(非推奨)

- WebLogic XML Streaming APIの概要

- WebLogic XML Streaming APIのJavadoc

- XMLドキュメントの解析:一般的な手順

- XMLドキュメント解析の例

- XML入力ストリームの取得

- バッファされたXML入力ストリームの取得

- XMLストリームのフィルタ処理

- カスタム・フィルタの作成

- ストリームの繰返し処理

- 特定のXMLEventタイプの判別

- 要素の属性の取得

- ストリームの位置決め

- サブストリームの取得

- バッファされたXML入力ストリームのマーキングとリセット

- 入力ストリームのクローズ

- 新しいXMLドキュメントの生成:一般的な手順

- XMLドキュメント生成の例

- XML出力ストリームの作成

- 出力ストリームへの要素の追加

- 出力ストリームの要素への属性の追加

- 出力ストリームへの入力ストリームの追加

- 出力ストリームの出力

- 出力ストリームのクローズ

Oracle® Fusion Middleware

Oracle WebLogic Server XMLアプリケーションの開発

12c (12.1.2)

E48050-01(原本部品番号:E28119-01)

2013年6月

このマニュアルは、XML処理を含むアプリケーションを設計および開発するソフトウェア開発者のための情報源です。

Oracle Fusion Middleware Oracle WebLogic Server XMLアプリケーションの開発, 12c (12.1.2)

E48050-01

Copyright © 2007, 2013, Oracle and/or its affiliates.All rights reserved.

このソフトウェアおよび関連ドキュメントの使用と開示は、ライセンス契約の制約条件に従うものとし、知的財産に関する法律により保護されています。ライセンス契約で明示的に許諾されている場合もしくは法律によって認められている場合を除き、形式、手段に関係なく、いかなる部分も使用、複写、複製、翻訳、放送、修正、ライセンス供与、送信、配布、発表、実行、公開または表示することはできません。このソフトウェアのリバース・エンジニアリング、逆アセンブル、逆コンパイルは互換性のために法律によって規定されている場合を除き、禁止されています。

ここに記載された情報は予告なしに変更される場合があります。また、誤りが無いことの保証はいたしかねます。誤りを見つけた場合は、オラクル社までご連絡ください。

このソフトウェアまたは関連ドキュメントを、米国政府機関もしくは米国政府機関に代わってこのソフトウェアまたは関連ドキュメントをライセンスされた者に提供する場合は、次の通知が適用されます。

U.S. GOVERNMENT END USERS: Oracle programs, including any operating system, integrated software, any programs installed on the hardware, and/or documentation, delivered to U.S. Government end users are "commercial computer software" pursuant to the applicable Federal Acquisition Regulation and agency-specific supplemental regulations.As such, use, duplication, disclosure, modification, and adaptation of the programs, including any operating system, integrated software, any programs installed on the hardware, and/or documentation, shall be subject to license terms and license restrictions applicable to the programs.No other rights are granted to the U.S. Government.

このソフトウェアもしくはハードウェアは様々な情報管理アプリケーションでの一般的な使用のために開発されたものです。このソフトウェアもしくはハードウェアは、危険が伴うアプリケーション(人的傷害を発生させる可能性があるアプリケーションを含む)への用途を目的として開発されていません。このソフトウェアもしくはハードウェアを危険が伴うアプリケーションで使用する際、安全に使用するために、適切な安全装置、バックアップ、冗長性(redundancy)、その他の対策を講じることは使用者の責任となります。このソフトウェアもしくはハードウェアを危険が伴うアプリケーションで使用したことに起因して損害が発生しても、オラクル社およびその関連会社は一切の責任を負いかねます。

OracleおよびJavaはOracle Corporationおよびその関連企業の登録商標です。その他の名称は、それぞれの所有者の商標または登録商標です。

Intel、Intel Xeonは、Intel Corporationの商標または登録商標です。すべてのSPARCの商標はライセンスをもとに使用し、SPARC International, Inc.の商標または登録商標です。AMD、Opteron、AMDロゴ、AMD Opteronロゴは、Advanced Micro Devices, Inc.の商標または登録商標です。UNIXは、The Open Groupの登録商標です。

このソフトウェアまたはハードウェア、そしてドキュメントは、第三者のコンテンツ、製品、サービスへのアクセス、あるいはそれらに関する情報を提供することがあります。オラクル社およびその関連会社は、第三者のコンテンツ、製品、サービスに関して一切の責任を負わず、いかなる保証もいたしません。オラクル社およびその関連会社は、第三者のコンテンツ、製品、サービスへのアクセスまたは使用によって損失、費用、あるいは損害が発生しても一切の責任を負いかねます。

はじめに

ここでは、このガイド『Oracle WebLogic Server XMLアプリケーションの開発』で使用されるドキュメント・アクセシビリティ機能と表記規則について説明します。

ドキュメントのアクセシビリティについて

Oracleのアクセシビリティについての詳細情報は、Oracle Accessibility ProgramのWebサイトhttp://www.oracle.com/pls/topic/lookup?ctx=acc&id=docaccを参照してください。

Oracleサポートへのアクセス

Oracleのお客様は、My Oracle Supportにアクセスして電子サポートを受けることができます。詳細情報はhttp://www.oracle.com/pls/topic/lookup?ctx=acc&id=infoか、聴覚に障害のあるお客様はhttp://www.oracle.com/pls/topic/lookup?ctx=acc&id=trsを参照してください。

表記規則

このマニュアルでは次の表記規則を使用します。

規則

意味

太字

太字は、操作に関連するGraphical User Interface要素、または本文中で定義されている用語および用語集に記載されている用語を示します。

斜体

イタリックは、ユーザーが特定の値を指定するプレースホルダー変数を示します。

固定幅フォント

固定幅フォントは、段落内のコマンド、URL、サンプル内のコード、画面に表示されるテキスト、または入力するテキストを示します。

1 概要とロードマップ

ここでは、このガイド『Oracle WebLogic Server XMLアプリケーションの開発』の内容と構成について説明します。

- ドキュメントの内容と対象読者

- このドキュメントの手引き

- 関連ドキュメント

- このリリースでのXMLの新機能と変更点

- WebLogic ServerのXML機能の概要

- 推奨規格オーバーライド機構によるDOM/SAXの切替え:サポート対象外

- XMLの詳細情報へのリンク

ドキュメントの内容と対象読者

このマニュアルは、XML処理を含むアプリケーションを設計および開発するソフトウェア開発者のための情報源です。

このマニュアルのトピックでは、ソフトウェア・プロジェクトの設計および開発段階に関連する情報を提供します。また、プロジェクトのテストおよびプロダクション前の段階で見つかるアプリケーションの問題を解決するうえで便利なトピックもあります。

このマニュアルでは、開発環境でアプリケーションをテストする際に役立つ管理およびモニター情報についても説明していますが、プロダクション段階でのXMLの管理、モニター、パフォーマンス・チューニングについては扱いません。これらのトピックに関するWebLogic Server ®のマニュアルとリソースへのリンクについては、「関連ドキュメント」を参照してください。

このマニュアルは、Webテクノロジ、XML、XSLT、Javaプログラミング言語、Java EE仕様のサーブレットとJSP APIに精通している読者を対象としています。このマニュアルでは、WebLogic Server XMLが提供する付加価値機能と、XML処理を実行するアプリケーションを動作させるためのWebLogic Server機能の使い方に関する主要な情報が重点的に扱われています。

このドキュメントの手引き

このマニュアルの構成は次のとおりです。

- この章第1章「概要とロードマップ」では、このガイドの構成とWebLogic Server XMLの機能を紹介します。

- 第2章「XMLの概要」では、XMLテクノロジとWebLogic Server XMLサブシステムについて概説します。

- 第3章「WebLogic Serverを使用したXMLアプリケーションの開発」では、XML APIとツールを使用してWebLogic Serverアプリケーション内からXMLドキュメントを処理する方法について説明します。主な処理タスクには、既存のXMLドキュメントの解析、新しいXMLドキュメントの生成、XMLドキュメントから別のフォーマットへの変換などがあります。

- 第4章「Streaming API for XML (StAX)の使い方」では、JavaアプリケーションでStreaming API for XML (StAX)を使用してXMLドキュメントを解析および生成する方法の詳細について説明します。

- 第5章「高度なXML APIの使い方」では、付加的なXML APIを使用して、XMLドキュメントに対するXPathマッチングなどの高度なタスクを実行する方法について説明します。

- 第6章「XMLプログラミングのベスト・プラクティス」では、XMLドキュメントを処理するJavaアプリケーションを作成する際に参考となるベスト・プラクティスをいくつかが説明します。

- 第7章「XMLプログラミング手法」では、XMLドキュメントでメッセージドリブンbeanとJMSキューを使用する場合など、いくつかのタスクに固有のプログラミング手法について説明します。

- 第8章「XMLアプリケーション・スコーピング」では、特定のエンタープライズ・アプリケーションのパーサー、トランスフォーマ、および外部エンティティを構成する方法について説明します。

- 第9章「WebLogic Server XMLの管理」では、管理コンソールのXMLレジストリおよびXML構成タスクの実行方法について説明します。

- 付録A「XMLリファレンス」では、XMLソフトウェアでサポートされている仕様およびアプリケーション・プログラミング・インタフェースへの参照先リストを示します。

- 付録B「WebLogic XML Streaming APIの使用(非推奨)」では、現在では非推奨になっているWebLogic XML Streaming APIの使い方について説明します。このトピックは、従来の技術からの連続性をサポートするためだけに記載されています。新しいアプリケーションではこのAPIを使用しないでください。新しいアプリケーションでは、第4章「Streaming API for XML (StAX)の使い方」で説明しているStAXを使用してください。

関連ドキュメント

このマニュアルには、XML固有の設計および開発上の情報が含まれています。

WebLogic Serverアプリケーションを開発、デプロイ、およびモニターするための包括的なガイドラインについては、以下のドキュメントを参照してください。

- 『Oracle WebLogic Serverアプリケーションの開発』は、WebLogic Serverコンポーネント(Webアプリケーション、EJBなど)およびアプリケーションの開発用ガイドです。

- 『Oracle WebLogic Server JAX-WS Webサービスの開発』は、WebLogic Serverにデプロイして実行するWebサービスの開発用ガイドです。

- 『Oracle WebLogic Serverへのアプリケーションのデプロイ』は、WebLogic Serverアプリケーションのデプロイメントについての情報のプライマリ・ソースです。

このマニュアルでは説明されていないXML関連情報については、付録A「XMLの詳細情報へのリンク」と「XMLリファレンス」にリストされているリンクを参照してください。

XML開発者向けのサンプル

このマニュアルの他にも、様々なサンプル・コードがXML開発者向けに用意されています。サンプルとチュートリアルではWebLogic Server XMLの動作が例示され、主要なXML開発タスクを実行する実際的な手順が示されています。

XMLを処理する独自のアプリケーションをプログラミングする前に、まずXMLサンプルの一部またはすべてを実行することをお薦めします。

WebLogic Server配布キットのXMLサンプル

WebLogic Serverでは、必要に応じてAPIサンプル・コードがEXAMPLES_HOME\wl_server\examples\src\examplesディレクトリ(EXAMPLES_HOMEはWebLogic Serverサンプル・コードが構成されているディレクトリ)にインストールされます。WebLogic Serverのサンプル・コードの詳細は、『Oracle WebLogic Serverの理解』のサンプル・アプリケーションおよびサンプル・コードに関する項を参照してください。

このリリースでのXMLの新機能と変更点

このリリースで導入されたWebLogic Serverの包括的な新機能一覧は、『Oracle WebLogic Serverの新機能』を参照してください。

WebLogic ServerのXML機能の概要

WebLogic Serverでは、WebLogic Serverに適用可能なXMLテクノロジと、WebLogic Serverに基づくXMLアプリケーションが統合されています。WebLogic Server XMLサブシステムを使用すると、顧客は、標準パーサー、WebLogic FastParser、XSLTトランスフォーマ、DTD、およびXMLスキーマを使用してXMLファイルを処理および変換できます。

この節では、WebLogic Server XMLサブシステムにある以下の機能が表示されています。

- XMLドキュメント・パーサー

- XMLドキュメント・トランスフォーマ

- Streaming API for XML (StAX)の実装

- WebLogic XPath API

- JAXPプラガブル・レイヤーの実装

- Java API for XML Registriesの実装

- WebLogicサーブレット属性

- WebLogic XSLT JSPタグ・ライブラリ

- パーサーおよびトランスフォーマの構成用XMLレジストリ

- 外部エンティティの解決の構成用XMLレジストリ

XMLドキュメント・パーサー

WebLogic Serverは、JDKバージョン5.0に付属のXMLパーサーをデフォルトで使用します。

管理コンソールによるXMLレジストリの構成では、他のあらゆるXMLパーサーを使用できます。単一のWebLogic Serverのインスタンスを構成することによって、あるパーサーを特定のアプリケーション用に使用し、別のパーサーを異なるアプリケーション用に使用できます。

XMLドキュメントの解析については、「XMLドキュメントの解析」を参照してください。

WebLogic Serverバージョン8.1と9.1のデフォルト・パーサーの違い

バージョン8.1およびそれ以前のWebLogic Serverにおけるデフォルトのパーサーは、ApacheのXercesをベースにしたもので、パッケージ名の先頭にはweblogic.apache.xerces.*が付いていました。バージョン9.1のWebLogic Serverでは、このパーサーは非推奨となりました。かわりに、デフォルトのパーサーはJDK 5.0に同梱されているものと同じです。

下位互換性のためweblogic.apache.xerces.*パーサーはバージョン9.1のWebLogic Serverでも使用できますが、これは現在は非推奨になっており今後のバージョンでは使用できなくなるので、使用しないことを強くお薦めします。ただし、一時的にこのパーサーを使用する必要がある場合は、管理コンソールを使用して、XMLレジストリを更新または新規作成し、表1-1で示すSAXおよびDOMパーサー・ファクトリ・インタフェースのデフォルト実装クラスを設定することにより、使用中のWebLogic Serverインスタンス用のデフォルトでないパーサーを構成しなければなりません。

表1-1 SAXおよびDOMパーサー・ファクトリ・インタフェースのデフォルト実装クラス

パーサー・ファクトリ・インタフェース

実装クラス

DOM (DocumentBuilderFactory)

weblogic.apache.xerces.jaxp.DocumentBuilderFactoryImpl

SAX (SAXParserFactory)

weblogic.apache.xerces.jaxp.SAXParserFactoryImpl

XMLレジストリの作成については、第9章「WebLogic Server XMLの管理」を参照してください。

XMLドキュメント・トランスフォーマ

WebLogic Serverは、JDKバージョン5.0に付属のXMLトランスフォーマをデフォルトで使用します。

管理コンソールによるXMLレジストリの構成では、他のあらゆるXMLトランスフォーマを使用できます。単一のWebLogic Serverのインスタンスを構成することによって、あるトランスフォーマを特定のアプリケーション用に使用し、別のトランスフォーマを異なるアプリケーション用に使用できます。

XMLドキュメントの変換については、「XMLドキュメントの変換」を参照してください。

Streaming API for XML (StAX)の実装

WebLogic Serverには、Streaming API for XML (StAX)の実装が含まれています。

詳細は、第4章「Streaming API for XML (StAX)の使い方」を参照してください。

WebLogic XPath API

WebLogic XPath APIには、DOM、XMLInputStream、またはXMLOutputStreamとして表現されるドキュメントに対してXPathのマッチングを実行するために必要となる、すべてのクラスが入っています。

詳細は、「WebLogic XPath APIの使い方」を参照してください。

JAXPプラガブル・レイヤーの実装

Java API for XML Processing (JAXP) 1.2は、Java標準で、パーサーに依存しないXML用APIです。JAXPの詳細は、「JAXPとは」を参照してください。

注意:

WebLogic Serverは、管理コンソールからアクセスされるXMLレジストリを使用して、パーサーとトランスフォーマをプラグインします。この点が、システム・プロパティを使用してパーサーとトランスフォーマをプラグインするように指定されたJAXP 1.2仕様との違いです。

Java API for XML Registriesの実装

http://www.oracle.com/technetwork/java/jaxr-138137.htmlのJava API for XML Registries (JAXR) APIは、様々なレジストリ、特にWebサービス・アプリケーションで使用されるXMLレジストリにアクセスするための共通の標準Java APIを提供しています。

詳細は、「Java API for XML Registries (JAXR) APIの使い方」を参照してください。

WebLogicサーブレット属性

WebLogic Serverは、以下の特殊なサーブレット属性をサポートします。

- org.xml.sax.HandlerBase

- org.xml.sax.helpers.DefaultHandler

- org.w3c.dom.Document

ServletRequestオブジェクトで、前述の属性を付けてsetAttributeメソッド(SAX解析の場合)およびgetAttributeメソッド(DOM解析の場合)を呼び出すと、任意のXMLドキュメントが解析されます。

詳細は、「サーブレットでのXMLドキュメントの解析」を参照してください。

WebLogic XSLT JSPタグ・ライブラリ

JSPタグ・ライブラリは、WebLogic Serverで動作するJava Server Page (JSP)内からデフォルトXSLTトランスフォーマにアクセスするための単純なタグを提供します。現時点では、このタグはデフォルトXSLTトランスフォーマだけをサポートしています。このタグを使用して、XMLドキュメントをJSP内から異なるトランスフォーマを使って変換することはできません。

注意:

この機能はWebLogic Server 12.1.2.0で非推奨となり、将来のリリースでは削除される可能性があります。

JSPタグ・ライブラリは、xmlx-tags.jarに収められています。このファイルは、WebLogic Server配布キットのインストール時に自動的にインストールされます。

詳細は、「JSPタグによるXMLデータの変換」を参照してください。

パーサーおよびトランスフォーマの構成用XMLレジストリ

XMLレジストリは、管理タスクと構成タスクをXMLアプリケーションから切り離すことによって、これらのタスクを簡素化します。管理コンソールを使用して、WebLogic Serverのインスタンスのパーサーとトランスフォーマを構成します。

詳細は、「XMLパーサーおよびトランスフォーマの構成タスク」を参照してください。

外部エンティティの解決の構成用XMLレジストリ

WebLogic XMLでは、XMLレジストリを使用して外部エンティティを解決できます。詳細は、「部エンティティの構成タスク」を参照してください。

推奨規格オーバーライド機構によるDOM/SAXの切替え:サポート対象外

WebLogic Serverでは、サーバーのDOMインタフェースとSAXインタフェースの推奨規格オーバーライド機構(Endorsed Standards Override Mechanism)を使用した切替えをサポートしていません。

推奨規格とは、Java Community Process (JCP)以外の標準プロセスを介して定義されたJava APIのことです。詳細については、http://docs.oracle.com/javase/6/docs/technotes/guides/standards/の推奨規格オーバーライド機構を参照してください。

XMLの詳細情報へのリンク

XMLについてさらに学習するには、以下のオンライン・コースおよびチュートリアルを参照してください。付録A「XMLリファレンス」には追加情報へのリンクがあります。

- XMLの技術概説: http://www.xml.com/pub/a/98/10/guide0.htmlで入手可能

- XMLオーサリング・チュートリアル: http://www.xml.com/pub/r/32で入手可能

- Java 2プラットフォームおよびXMLテクノロジを使用するためのチュートリアル: http://developerlife.com/で入手可能

- XML、Java、そしてWebの未来: http://www.xml.com/pub/a/w3j/s3.bosak.htmlで入手可能

- XMLバイブルの第17章「XSL変換」: http://metalab.unc.edu/xml/books/bible/updates/14.htmlで入手可能

- 『XSL Tutorial』(Nic Miloslav著): http://zvon.org/xxl/XSLTutorial/Output/index.htmlで入手可能

- SAX 2.0: XMLのための簡易API: http://www.saxproject.org/で入手可能

- ドキュメント・オブジェクト・モデル(DOM): http://www.w3.org/DOM/で入手可能

2 XMLの概要

この章では、Extensible Markup Language (XML)テクノロジおよびWebLogic Server XMLサブシステムについて説明します。

この章の内容は以下のとおりです。

- XMLとは

- XMLドキュメントの記述方法

- XMLを使用する理由

- XSLとXSLTとは

- DOMとSAXとは

- Streaming API for XML (StAX)とは

- JAXPとは

- XMLとXSLTの一般的な使い方

XMLとは

Extensible Markup Language (XML)とは、ドキュメント内のデータの内容および構造を示すのに使用するマークアップ言語です。それは、Standard Generalized Markup Language (SGML)を簡素化したバージョンです。XMLは、インターネット上でコンテンツを配信するための業界標準です。XMLには新しいタグを定義する機能があるので、拡張が可能です。

HTMLと同じように、XMLでもタグを使用してコンテンツを記述します。しかし、XMLのタグはコンテンツの表示方法ではなく、データの意味と階層構造を表します。この機能を使用すれば、異なるプログラムやシステム間でのデータ交換を効率化するために必要な高度なデータ型を定義できます。さらに、XMLではコンテンツと表現を分離できるため、コンテンツ(データ)を異種システム間で移植できます。

XML構文では、一対の開始タグと終了タグ(<name>と</name>など)を使用して情報をマークアップします。タグで区切られる情報のことを、要素と呼びます。どのXMLドキュメントにもルート要素が1つあります。ルート要素は、他のすべての要素を含む最上位の要素です。他の要素内に含まれる要素をしばしば下位要素と言います。要素には、名前と値のペアという構造の属性が付くことがあります。属性は、要素の一部として要素をさらに定義するのに使用します。

次のサンプルXMLファイルでは、アドレス帳の内容を説明します。

<?xml version="1.0"?>

<address_book>
<person gender="f">
<name>Jane Doe</name>
<address>
<street>123 Main St.</street>
<city>San Francisco</city>
<state>CA</state>
<zip>94117</zip>
</address>
<phone area_code=415>555-1212</phone>
</person>
<person gender="m">
<name>John Smith</name>
<phone area_code=510>555-1234</phone>
<email>johnsmith@somewhere.com</email>
</person>
</address_book>

XMLファイルのルート要素はaddress_bookです。アドレス帳には現在、person要素の形で「Jane Doe」と「John Smith」の2つのエントリがあります。Jane Doeのエントリには住所と電話番号、John Smithのエントリには電話番号と電子メール・アドレスがあります。このXMLドキュメントの構造では、要素の本体の下位要素ではなく、phone要素にarea_code属性を指定して市外局番を格納するように定義しています。すべての下位要素がperson要素で必須であるわけではないことにも注意してください。

XMLドキュメントの記述方法

XMLドキュメントの記述方法には、XMLスキーマとDTDの2種類があります。

XMLスキーマは、特定のXMLドキュメントの構造で基本的に必要なものを定義します。スキーマでは、XMLドキュメントで有効な要素と属性、およびそれらが有効となるコンテキストを定義します。言い換えれば、スキーマでは特定のタグ内で有効なタグ、およびオプションのタグと属性を指定します。スキーマは、それ自体がXMLファイルです。

スキーマ仕様は、World Wide Web Consortium (W3C)によって策定されました。XMLスキーマの詳細は、http://www.w3.org/TR/xmlschema-0/を参照してください。

次の例では、上のアドレス帳のサンプルXMLドキュメントを定義するスキーマを示します。

<xsd:schema xmlns:xsd="http://www.w3.org/1999/XMLSchema">

<xsd:complexType name="personType">
<xsd:element   name="name"     type="xsd:string"/>
<xsd:element   name="address"  type="addressType"/>
<xsd:element   name="phone"    type="phoneType"/>
<xsd:element   name="email"    type="xsd:string"/>
<xsd:attribute name="gender"   type="xsd:string"/>
</xsd:complexType>

<xsd:complexType name="addressType">
<xsd:element   name="street"  type="xsd:string"/>
<xsd:element   name="city"    type="xsd:string"/>
<xsd:element   name="state"   type="xsd:string"/>
<xsd:element   name="zip"     type="xsd:string"/>
</xsd:complexType>

<xsd:simpleType name="phoneType">
<xsd:restriction base="xsd:string"/>
<xsd:attribute name="area_code" type="xsd:string"/>
</xsd:simpleType>

</xsd:schema>

XMLスキーマよりも古いテクノロジである文書型定義(Document Type Definition : DTD)ファイルを使用してXMLドキュメントを記述することもできます。DTDはXMLファイルではありません。

次の例では、上のアドレス帳のサンプルXMLドキュメントを定義するDTDを示します。

<!DOCTYPE address_book [
<!ELEMENT person (name, address?, phone?, email?)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT address (street, city, state, zip)>
<!ELEMENT phone (#PCDATA)>
<!ELEMENT email (#PCDATA)>
<!ELEMENT street (#PCDATA)>
<!ELEMENT city (#PCDATA)>
<!ELEMENT state (#PCDATA)>
<!ELEMENT zip (#PCDATA)>
<!ATTLIST person gender CDATA #REQUIRED>
<!ATTLIST phone area_code CDATA #REQUIRED>
]>

XMLドキュメントでは、ドキュメント自体の一部としてスキーマまたはDTDを指定することも、外部スキーマまたはDTDを参照することも、スキーマやDTDをまったく指定または参照しないようにすることもできます。次のXMLドキュメントの抜粋に、address.dtdという外部DTDを参照する方法を示します。

<?xml version=1.0?>
<!DOCTYPE address_book SYSTEM "address.dtd">
<address_book>
...

XMLドキュメントは、パーサーで検証する場合、または複雑なタイプが含まれる場合にのみスキーマまたはDTDを付ける必要があります。XMLドキュメントは、1)関連するスキーマまたはDTDがある場合、および2)関連するスキーマまたはDTDに定義されている制約に準拠している場合に有効であると見なされます。ただし、XMLドキュメントが整形式でなければならない場合は、ドキュメントにスキーマまたはDTDを付ける必要はありません。W3CのXML 1.0勧告のすべてのルールに従っている場合、ドキュメントは整形式と見なされます。XML 1.0仕様の完全な説明については、http://www.w3.org/XML/を参照してください。

XMLを使用する理由

通常、ある業界では、その業界にとって意味がある固有のデータ交換方式を使用しています。電子商取引の誕生により、企業では様々な業界と関係を結ぶようになっています。このため、こうした企業は、これらの業界で使用される様々な電子通信プロトコルに関する専門知識を取得しなければなりません。

XMLは拡張性に優れているため、様々な業界間のデータ交換フォーマットを標準化するための非常に効果的なツールとなっています。たとえば、複数の業界間または一企業内の複数の部門間でメッセージ・ブローカとワークフロー・エンジンがトランザクションを調整しなければならない場合、XMLを使用すると、異なるソースからのデータを組み合せて、すべての当事者が理解できる1つのフォーマットを作成できます。

XSLとXSLTとは

Extensible Stylesheet Language (XSL)は、XMLドキュメントに適用する表示のルールを記述するためのW3Cの規格です。XSLには、変換言語(XSLT)とフォーマット言語の両方が含まれます。この2つの言語は、互いに独立して機能します。XSLTはXMLベースの言語で、XMLドキュメントを別のXMLドキュメントに、またはHTML、PDF、その他の文書フォーマットに変換する方法を記述するためのW3Cの仕様です。

XSLTトランスフォーマは、XMLドキュメントとXSLTドキュメントを入力として受け付けます。XSLTドキュメントに定義されるテンプレート・ルールには、そのルールの適用先となるXMLツリーを指定するパターンが含まれています。XSLTトランスフォーマは、XMLドキュメントをスキャンしてルールに一致するパターンを見つけ出し、元のXMLドキュメントの該当するセクションにテンプレートを適用します。

DOMとSAXとは

DOMおよびSAXは、XMLデータ解析のための2つの標準Javaアプリケーション・プログラミング・インタフェース(API)です。いずれも、WebLogic Serverデフォルト・パーサーによりサポートされます。この2つのAPIは、解析に対して異なるアプローチをとっており、それぞれのAPIに長所と短所があります。

SAX

SAXはSimple API for XMLの略語です。イベント・ベースのXML解析用標準インタフェースで、プラットフォームや言語に依存しません。SAXは、パーサーが要素の最初または最後などのXMLドキュメントを読み取る際に発生するイベントを定義します。プログラマは、ドキュメント解析時に異なるイベントを処理するハンドラを提供します。

XMLドキュメントを解析するためにSAX APIを使用するプログラマは、これらのイベントが発生したときに起こることを完全に制御する権限を持ち、解析プロセスをカスタマイズできます。たとえば、プログラマは、ドキュメントが不正であることを示すエラーがパーサーで発生したときに、ドキュメントがすべて解析されるまで待つのではなく、すぐにXMLドキュメントの解析を中止できるので、パフォーマンスが向上します。

WebLogic Serverのデフォルト・パーサー(JDK 5.0に付属のパーサー)は、SAXバージョン2.0をサポートしています。SAXバージョン1.0を使用してXMLドキュメントを解析するプログラムを作成した場合は、2つのバージョンの相違点を把握し、それに従ってプログラムを更新する必要があります。2つのバージョンの相違点については、http://www.saxproject.org/を参照してください。

DOM

DOMはDocument Object Model の略語です。プラットフォームや言語に依存しないインタフェースであり、これを使用することにより、プログラムとスクリプトはXMLドキュメントのコンテンツ、構造、およびスタイルに動的にアクセスして、それらを更新できます。DOMは、XMLドキュメントをメモリーに読み込んでツリー表示します。ツリーの各ノードは、元のXMLドキュメントからの特定のデータの一部を表します。ツリー構造は、データを表すための標準プログラミング・メカニズムで、Javaを使用したツリーのナビゲートおよび操作を簡単に素早く、かつ効率的に実行できます。しかし、DOMでツリーを作成するためにXMLドキュメント全体をメモリーに読み込む必要があるため、XMLドキュメントのサイズが大きくなると、アプリケーションのパフォーマンスが低下するという欠点があります。

WebLogic Serverのデフォルト・パーサー(JDK 5.0に付属のパーサー)は、DOM Level 2.0 Coreをサポートしています。DOM Level 1.0を使用してXMLドキュメントを解析するプログラムを作成した場合は、2つのバージョンの相違点を把握し、それに従ってプログラムを更新する必要があります。相違点の詳細は、http://www.w3.org/DOM/DOMTRを参照してください。

Streaming API for XML (StAX)とは

SAXとDOMだけでなく、Streaming API for XML (StAX)を使用してXMLドキュメントを解析および生成することもできます。

StAXは、XMLを読み書きするための双方向APIを記述するJava Community Process仕様です。StAXを使用すると、単純なイテレータ・ベースのAPIとイベントの基底のストリームを公開することで、解析を制御できます。APIには、コールバック内のイベントを処理するのではなく次のイベントを問い合せることができるnext()やhasNext()などのメソッドがあります。これにより、より整った手順に従ってXMLドキュメントを処理できるようになります。

DOMやSAXと異なり、StAXは、まだJava API for XML Processing (JAXP)の一部ではありません。

注意:

旧バージョンのWebLogic Serverには、これによく似たWebLogic XML Streaming APIという独自のAPIがありました。StAXは、このAPIを基にしています。WebLogic XML Streaming APIはこのリリースのWebLogic Serverでもアクセス可能ですが、その機能はWebLogic Serverリリース9.0の時点で非推奨になっています。プログラマは、かわりにStAXを使用してください。

StAXの使用の詳細は、第4章「Streaming API for XML (StAX)の使い方」を参照してください。

JAXPとは

前の節では、XMLデータの解析に使用できるAPI、SAX、DOMについて説明しました。Java API for XML Processing (JAXP)は、これらのパーサーにアクセスする手段を提供します。JAXPはまた、どのような仕様のパーサーまたはトランスフォーマも使用できるプラガブル・レイヤーも定義します。

WebLogic Serverには、XMLアプリケーションの開発と、WebLogic Serverで構築したXMLアプリケーションを他のWebアプリケーション・サーバーに移植するのに必要な作業を容易にするために、JAXPが実装されています。JAXPは、XMLアプリケーションの移植性を高めるために開発されました。JAXPでは、JavaプラットフォームのAPIの標準セットを介してXMLドキュメントを解析および変換するための基本機能がサポートされています。WebLogic Server配布キット内のJAXP 1.2は、デフォルト・パーサーを使用する構成になっています。したがって、WebLogic Serverで構築されるXMLアプリケーションでは、デフォルトでJAXPを使用します。

WebLogic Server配布キットには、JAXP 1.2で必要なインタフェースとクラスがあります。JAXP 1.2は、SAXバージョン2とDOM Level 2を明示的にサポートしています。

JAXPパッケージ

JAXPには、以下の2つのパッケージがあります。

- javax.xml.parsers

- javax.xml.transform

javax.xml.parsersパッケージには、SAXバージョン2.0およびDOM Level 2.0モードでXMLデータを解析するためのクラスがあります。XMLドキュメントをSAXモードで解析するには、まずnewInstance()メソッドで新しいSaxParserFactoryオブジェクトのインスタンスを作成します。このメソッドは、明確に定義された場所のリストを基に、ロードするパーサーの特定の実装をルックアップします。次に、SaxParserFactoryからSaxParserインスタンスを取得し、そのparse()メソッドを実行して、解析するXMLドキュメントにそれを渡します。XMLドキュメントをDOMモードで解析する場合に似ていますが、この場合はDocumentBuilderクラスとDocumentBuilderFactoryクラスを使用します。

JAXPによるXMLドキュメント解析の詳細は、「XMLドキュメントの解析」を参照してください。

javax.xml.transformパッケージには、XMLドキュメント、DOMツリー、SAXイベントなどのXMLデータを別の形式に変換するためのクラスがあります。トランスフォーマ・クラスも、パーサー・クラスと同じように機能します。XMLドキュメントを変換するには、まずnewInstance()メソッドで新しいTransformerFactoryオブジェクトのインスタンスを作成します。このメソッドは、明確に定義された場所のリストを基に、ロードするXSLTトランスフォーマの特定の実装をルックアップします。次に、特定のXSLTスタイルシートを基に新しいTransformerオブジェクトのインスタンスを作成し、そのtransform()メソッドを実行して、変換するXMLオブジェクトに渡します。XMLオブジェクトは、XMLファイルでもDOMツリーなどでもかまいません。

JAXPによるXMLオブジェクト変換の詳細は、「JAXPによるXMLデータの変換」を参照してください。

JAXP 1.2の新機能

Java EE 1.4には、バージョン1.2のJAXPが含まれています。JAXPバージョン1.2は、1.1バージョンを基に、W3C XMLスキーマのサポートを加えたものです。特に、1.2のバージョンは、XMLスキーマ検証を有効にする新しいプロパティ文字列、使用するスキーマ言語、XMLファイルの検証時に使用する特定のXMLスキーマ・ファイルの場所を指定します。

以下のコードの抜粋では、SAXパーサー使用時のスキーマ検証を設定する方法を示します。

try {
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setNamespaceAware(true);
spf.setValidating(true);
SAXParser sp = spf.newSAXParser();
sp.setProperty("http://java.sun.com/xml/jaxp/properties/schemaLanguage",
"http://www.w3.org/2001/XMLSchema");
sp.setProperty("http://java.sun.com/xml/jaxp/properties/schemaSource",
"http://www.example.com/Report.xsd");
DefaultHandler dh = new DefaultHandler();
sp.parse("http://www.wombats.com/foo.xml", dh);
} catch(SAXException se) {
se.printStackTrace();
}

詳細は、http://docs.oracle.com/javase/6/docs/technotes/guides/xml/jaxp/index.htmlを参照してください。

XMLとXSLTの一般的な使い方

XMLとXSLTをどのように使用するかは、ビジネス上のニーズによって異なります。

XMLとXSLTを使用したコンテンツと表示の分離

XMLとXSLTは、複数のクライアント・タイプをサポートするアプリケーションでよく使用されます。たとえば、ブラウザ・ベースのクライアントとWireless Application Protocol (WAP)クライアントの両方をサポートするWebベース・アプリケーションを使用しているとします。これらのクライアントでは、それぞれHTMLとWireless Markup Language (WML)という異なるマーク付け言語を理解しますが、アプリケーションでは両方に適したコンテンツを提供しなければなりません。

これを実現するには、クライアントに送信するデータを表すXMLドキュメントを最初に作成するようにアプリケーションを記述します。次に、アプリケーションは、データを表すXMLドキュメントを、クライアントのブラウザ・タイプによってHTMLまたはWMLに変換します。アプリケーションでは、HTTPリクエストのUser-Agentリクエスト・ヘッダーを調べることによって、クライアントのブラウザ・タイプを認識できます。クライアントのブラウザ・タイプを認識すると、適切なXSLTスタイル・シートを使用して、適切なマーク付け言語にドキュメントを変換します。このヘッダー情報へのアクセス方法の例については、WebLogic Server配布キットのexamples/servletsディレクトリに収められているSnoopServletサンプルを参照してください。

このように、クライアント・タイプごとに異なるマーク付け言語を使用して同じXMLドキュメントを表示する方法を用いると、複数のクライアント・タイプのサポートに必要な努力を、適切なXSLTスタイル・シートの開発に集中させることができます。さらに、必要な場合は、アプリケーションを他のクライアント・タイプに簡単に適合させることができます。

XSLTの詳細は、「その他のXML仕様と情報」を参照してください。

企業間通信用メッセージ・フォーマットとしてのXML

企業間(B2B)環境で、企業Aと企業Bは両者間の電子商取引に関する情報の交換を望んでいます。企業Aは大手の電子商取引サイトです。企業Bは、企業Aの製品を最適な顧客集団に販売する小規模な子会社です。企業Bが企業Aに顧客情報を送ると、企業Bは企業Aから2通りの方法で対価を受け取ることができます。企業Bは、金銭、および企業Bが提供した顧客と同じ購買層の他の顧客に関する情報を企業Aから受け取ります。情報を交換するためには、企業Aと企業Bは、マシンが理解できてどちらの企業のシステムでも簡単に処理できるデータ・フォーマットについて合意する必要があります。XMLは、このシナリオで使用する論理データ・フォーマットですが、このフォーマットの選択はほんの第一歩にすぎません。次に両企業は、交換するXMLメッセージのフォーマットについて合意しなければなりません。企業Aはその子会社と1対多の関係にあるため、やり取りするXMLメッセージのフォーマットは企業A側で定義する必要があります。

XMLメッセージ、つまりXMLドキュメントのフォーマットを定義するために、企業Aは2種類の文書型定義(DTD)を作成します。1つは企業Aが提供する顧客情報を記述するもので、もう1つは企業Aが受け取る新しい子会社の情報を記述するものです。企業Bも、2種類のDTDを作成します。1つは企業Aから受け取るXMLドキュメントを処理するためのもの、もう1つは企業A側で処理できるフォーマットでXMLドキュメントを作成するためのものです。

3 WebLogic Serverを使用したXMLアプリケーションの開発

この章では、Javaプログラミング言語とWebLogic Server XMLサブシステムを使用してXMLアプリケーションを開発する方法について説明します。ここでは、JavaサーブレットとJava Server Pages (JSP)を使用してJavaアプリケーションを記述する方法について理解していることを前提にしています。

この章の内容は以下のとおりです。

- XMLアプリケーションの開発:主な手順

- XMLドキュメントの解析

- 新しいXMLドキュメントの生成

- XMLドキュメントの変換

サーブレットとJSPアプリケーションの記述方法については、『Oracle WebLogic Server Webアプリケーション、サーブレット、JSPの開発』を参照してください。

XMLアプリケーションの開発:主な手順

WebLogic Server XMLサブシステムを使用してXMLアプリケーションを開発する場合、通常は以下のプログラミング・タスクの一部または全部を実行します。

1. XMLドキュメントを解析します。
XMLドキュメントは、いくつものソースから生じる可能性があります。たとえば、クライアントからのXMLドキュメントを受信するためにサーブレットを開発したり、サーブレットまたはその他のEJBなどからのXMLドキュメントを受信するためにEJBを記述したりする必要が生じるでしょう。それぞれのインスタンスでは、XMLドキュメントを解析してデータを操作できるようにすることが必要な場合もあります。

このタスクの詳細は、「XMLドキュメントの解析」を参照してください。

2. 新しいXMLドキュメントを生成します。
サーブレットまたはEJBがXMLドキュメントを受信および解析し、何らかの形でデータを操作したら、サーブレットまたはEJBは、新しいXMLドキュメントを生成してクライアントに返すか、他のEJBに渡さなければならないことがあります。

このタスクの詳細は、「新しいXMLドキュメントの生成」を参照してください。

3. XMLデータを他の形式に変換します。
XMLドキュメントを解析するか、新しいXMLドキュメントを生成したら、サーブレットまたはEJBは、そのXMLをHTML、WML、またはプレーン・テキストなどの形式に変換しなければならないことがあります。

このタスクの詳細は、「JAXPによるXMLデータの変換」を参照してください。

XMLドキュメントの解析

この節では、JAXPによりDOMモードとSAXモードでXMLドキュメントを解析する方法、およびサーブレットからXMLドキュメントを解析する方法について説明します。

注意:

Streaming API for XML (StAX)を使用したXMLドキュメントの解析方法の詳細は、第4章「Streaming API for XML (StAX)の使い方」を参照してください。

管理コンソールのXMLレジストリを使用して以下の項目を構成します。

- ドキュメント・タイプごとのパーサー。指定したドキュメント・タイプのデフォルト・パーサーのかわりに使用されます。

- 外部エンティティの解決。XMLドキュメントの解析中に外部ファイルを見つけるように要求された場合にXMLパーサーが実行する処理です。

管理コンソールでこれらのタスクを実行する方法については、第9章「WebLogic Server XMLの管理」を参照してください。

SAXモードでJAXPを使用したXMLドキュメントの解析

次のサンプル・コードは、SAXパーサー・ファクトリを構成して検証パーサーを作成する方法を示したものです。また、MyHandlerクラスをパーサーに登録する方法も示しています。MyHandlerクラスは、SAX解析イベントまたはエラーのカスタム動作を提供するためにDefaultHandlerクラスの任意のメソッドをオーバーライドできます。

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

...
MyHandler handler = new MyHandler();
// MyHandler extends org.xml.sax.helpers.DefaultHandler.

//Obtain an instance of SAXParserFactory.
SAXParserFactory spf = SAXParserFactory.newInstance();
//Specify a validating parser.
spf.setValidating(true); // Requires loading the DTD.
//Obtain an instance of a SAX parser from the factory.
SAXParser sp = spf.newSAXParser();
//Parse the documnt.
sp.parse("http://server/file.xml", handler);
...

注意:

デフォルト・パーサー以外のパーサーを使用する場合は、WebLogic Server管理コンソールを使用してXMLレジストリでパーサーを指定します。指定しなかった場合、SaxParserFactory.newInstanceメソッドはデフォルト・パーサーを返します。デフォルト・パーサー以外のパーサーを使用するWebLogic Serverの構成手順については、「デフォルト以外のパーサーまたはトランスフォーマの構成」を参照してください。

DOMモードでJAXPを使用したXMLドキュメントの解析

次のサンプル・コードでは、XMLドキュメントを解析し、DocumentBuilderオブジェクトからorg.w3c.dom.Documentツリーを作成する方法を示します。

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;

...
//Obtain an instance of DocumentBuilderFactory.
DocumentBuilderFactory dbf =
DocumentBuilderFactory.newInstance();
//Specify a validating parser.
dbf.setValidating(true); // Requires loading the DTD.
//Obtain an instance of a DocumentBuilder from the factory.
DocumentBuilder db = dbf.newDocumentBuilder();
//Parse the document.
Document doc = db.parse(inputFile);
...

注意:

デフォルト・パーサー以外のパーサーを使用する場合は、WebLogic Server管理コンソールでパーサーを指定します。指定しなかった場合、DocumentBuilderFactory.newInstanceメソッドはデフォルト・パーサーを返します。デフォルト・パーサー以外のパーサーを使用するWebLogic Serverの構成手順については、「デフォルト以外のパーサーまたはトランスフォーマの構成」を参照してください。

サーブレットでのXMLドキュメントの解析

Javaサーブレット仕様バージョン2.2で、setAttributeメソッドとgetAttributeメソッドのサポートが追加されました。属性は、リクエストに関連付けられたオブジェクトです。リクエスト・オブジェクトは、クライアント・リクエストからの全情報をカプセル化します。HTTPプロトコルでは、この情報は、リクエストのHTTPヘッダーとメッセージ本文を基にクライアントからサーバーに転送されます。

WebLogic Serverでは、setAttributeメソッドとgetAttributeメソッドを使用してXMLドキュメントを解析できます。「org.xml.sax.DefaultHandler属性を使用したドキュメントの解析」および「org.w3c.dom.Document属性を使用したドキュメントの解析」の説明に従って、SAXモードの検証ではsetAttributeメソッド、DOMモードの検証ではgetAttributeメソッドを使用します。

ただし、setAttributeメソッドおよびgetAttributeメソッドを使用できるようにするには、デフォルトですべてのWebLogic Serverインスタンスにデプロイされているweblogic.servlet.XMLParsingHelperというWebLogic Serverサーブレット・フィルタをWebアプリケーションの一部として構成する必要があります。WebアプリケーションのWEB-INFディレクトリにあるweb.xmlデプロイメント記述子に次の要素を追加してサーブレット・フィルタを構成します。

<filter>
<filter-name>XMLParsingHelper</filter-name>
<filter-class>weblogic.servlet.XMLParsingHelper</filter-class>
</filter>

<filter-mapping>
<filter-name>XMLParsingHelper</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>

サーブレット・フィルタの詳細は、『Oracle WebLogic Server Webアプリケーション、サーブレット、JSPの開発』のフィルタに関する項を参照してください。

org.xml.sax.DefaultHandler属性を使用したドキュメントの解析

次のサンプル・コードでは、setAttributeメソッドの使い方を示します。

import weblogic.servlet.XMLProcessingException;
import org.xml.sax.helpers.DefaultHandler;
...
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException  {
try {
request.setAttribute("org.xml.sax.helpers.DefaultHandler",
new DefaultHandler());
} catch(XMLProcessingException xpe) {
System.out.println("Error in processing XML");
xpe.printStackTrace();
return;
}
...

また、現在は非推奨となっていますが、org.xml.sax.HandlerBase属性を使用してXMLドキュメントを解析することもできます。

request.setAttribute("org.xml.sax.HandlerBase",
new HandlerBase());

注意:

このサンプル・コードは、SAXとsetAttributeメソッドでドキュメントを解析する単純な方法を示したものです。ドキュメントを解析するこのメソッドは、他のサーブレット・ベンダーではサポートされていないWebLogic Serverの便利な機能です。したがって、アプリケーションを他のサーブレット・プラットフォームで実行する場合は、この機能を使用しないでください。

org.w3c.dom.Document属性を使用したドキュメントの解析

次のサンプル・コードでは、getAttributeメソッドの使い方を示します。

import org.w3c.dom.Document;
import weblogic.servlet.XMLProcessingException;

...

public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException  {

try {
Document doc = request.getAttribute("org.w3c.dom.Document");
} catch(XMLProcessingException xpe) {
System.out.println("Error in processing XML");
xpe.printStackTrace();
return;
}
...

注意:

このサンプル・コードは、DOMとgetAttributeメソッドでドキュメントを解析する単純な方法を示したものです。ドキュメントを解析するこのメソッドは、他のサーブレット・ベンダーではサポートされていないWebLogic Serverの便利な機能です。したがって、アプリケーションを他のサーブレット・プラットフォームで実行する場合は、この機能を使用しないでください。

検証パーサーと非検証パーサー

前述のとおり、整形式ドキュメントとは、W3CのXML 1.0勧告のルールに従っている、構文的に正しいドキュメントのことです。有効なドキュメントとは、DTDまたはスキーマで指定した制約に従っているドキュメントです。

非検証パーサーは、ドキュメントが整形式かどうかを検証しますが、有効かどうかは検証しません。(検証パーサーの使用を前提に)ドキュメント解析時の検証を有効にするには、以下を実行する必要があります。

- 以下の例で示すように、SAXParserFactory.setValidating()メソッドをtrueに設定します。

SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setValidating(true);

- 解析するXMLドキュメントで、(インラインまたは参照で) DTDまたはスキーマが定義されているようにします。

XMLドキュメント解析時のエンティティ解決の処理

この節では、XMLパーサーによる外部エンティティの識別および解決方法、およびXMLアプリケーションによる外部エンティティ解決のパフォーマンスを向上させるWebLogic Serverの機能など、外部エンティティに関する一般的な情報について説明します。

外部エンティティに関する一般的な情報

外部エンティティは、XMLドキュメント内に記述されていないものの、XMLドキュメント内で参照される様々なテキストです。実際のテキストは、同じコンピュータの他のファイル、Web上など、どこにあってもかまいません。パーサーは、ドキュメントの解析時に外部エンティティ参照に出会うと、参照されたテキストをフェッチし、テキストをXMLドキュメント内に配置してから、解析を続行します。外部エンティティの例がDTDです。XMLドキュメント内にDTDのテキストがすべて記述されているのではなく、別のファイルに格納されているDTDへの参照がXMLドキュメント内にあります。

外部エンティティの識別方法には、システムIDとパブリックIDの2つがあります。システムIDは、URIで指定された位置を基に外部エンティティを参照します。パブリックIDは、外部で宣言されている名前を使用して情報を参照します。

次の例では、パブリックIDを使用して、Java EEアプリケーション・アーカイブ(*.ear)を示すapplication.xmlファイルのDTDを参照する方法を示します。

<!DOCTYPE application PUBLIC "-//Sun Microsystems,
Inc.//DTD J2EE Application 1.2//EN">

次の例は、システムIDのみによる外部DTDの参照を示します。

<!DOCTYPE application SYSTEM "http://java.sun.com/j2ee/dtds/application_1_2.dtd">

次の例は、パブリックIDおよびシステムIDの両方を使用する参照です。SYSTEMキーワードが省略されています。

<!DOCTYPE application
PUBLIC "-//Sun Microsystems, Inc.//DTD J2EE Application 1.2//EN"
"http://java.sun.com/j2ee/dtds/application_1_2.dtd">

WebLogic Serverのエンティティ解決機能の使用

以下のWebLogic Server機能を使用すると、XMLアプリケーションの外部エンティティ解決のパフォーマンスを向上させることができます。

- 外部エンティティのコピーを、WebLogic管理サーバーのホストとなるコンピュータに永続的に格納します。

- WebLogic Serverが、URLなどのHTTPインタフェースをサポートする外部リポジトリにある外部エンティティを自動的に取得およびキャッシュするように指定します。エンティティのキャッシュ先をメモリーにするかディスクにするかを指定し、キャッシュされているエントリが自動的に更新されるキャッシュの有効期限を指定できます。
この取出し/キャッシュ機能を使用すると、実際に外部エンティティをローカル・コンピュータにコピーする必要はなくなります。XMLアプリケーションは、ドキュメントを解析するたびにではなく、指定した期間でのみ外部エンティティを参照するので、アプリケーションのパフォーマンスを大幅に向上させることができ、必要に応じて外部エンティティを最新の状態で参照できます。

XMLレジストリで、外部エンティティの場所(ローカルまたはURL)、およびどのキャッシュ・オプションがWeb上のエンティティ用かを識別するエンティティ解決エントリを作成します。システムIDまたはパブリックIDを使用して外部エンティティ・エントリを識別します。次に、XMLドキュメントで、この外部エンティティを参照すると、WebLogic Serverは、ドキュメントの解析時にローカル・コピーまたはキャッシュされたコピー(構成による)を取り出します。

XMLレジストリでの外部エンティティ・レジストリ作成の詳細は、「外部エンティティの構成タスク」を参照してください。

デフォルト・パーサー以外のパーサーの使用

JAXPでXMLドキュメントを解析する場合、WebLogic Server XMLレジストリ(管理コンソールで構成)には以下の選択肢があります。

- デフォルト・パーサーをサーバー全体のパーサーとして使用します。

- 選択した別のパーサー(別のバージョンのApache Xercesパーサーなど)をサーバー全体のパーサーとして構成します。

- システムID、パブリックID、またはルート要素に基づいた特定のXMLドキュメント・タイプに対応するパーサーを構成します。

XMLレジストリで解析オプションを構成する手順については、「XMLパーサーおよびトランスフォーマの構成タスク」を参照してください。

新しいXMLドキュメントの生成

この節では、DOMドキュメント・ツリーからJSPを使用してXMLドキュメントを生成する方法について説明します。

注意:

Streaming API for XML (StAX)を使用したXMLドキュメントの解析方法の詳細は、第4章「Streaming API for XML (StAX)の使い方」を参照してください。

DOMドキュメント・ツリーからのXMLの生成

サンプル・コードの次のセグメントで示すように、javax.xml.transform.Transformerクラスを使用して、DOMオブジェクトをXMLストリームにシリアライズできます。

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;

import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import java.io.*;

...

TransformerFactory trans_factory = TransformerFactory.newInstance();
Transformer xml_out = trans_factory.newTransformer();
Properties props = new Properties();
props.put("method", "xml");
xml_out.setOutputProperties(props);
xml_out.transform(new DOMSource(doc), new StreamResult(System.out));

この例では、Transformer.transform()メソッドがDOMオブジェクトをXMLストリームに変換します。transform()メソッドは、doc変数に格納されているDOMツリーから作成されたjavax.xml.transform.dom.DOMSourceオブジェクトを入力としてとり、それをjavax.xml.transform.stream.StreamResultオブジェクトに変換して、結果として得られるXMLドキュメントを標準出力に書き出します。

JSPでのXMLドキュメントの生成

通常、JSPはHTMLの生成に使用しますが、JSPを使用してXMLドキュメントを生成することもできます。

JSPによるXMLの生成には、以下のようにJSPページのコンテンツ・タイプを設定する必要があります。

<%@ page contentType="text/xml"%>
... XML document

次のコードでは、JSPによるXMLドキュメントの生成例を示します。

<?xml version="1.0">

<%@ page contentType="text/xml" import="java.text.DateFormat,java.util.Date" %>

<message>
<text>
Hello World.
</text>
<timestamp>
<%
out.print(DateFormat.getDateInstance().format(new Date()));
%>
</timestamp>
</message>

XMLドキュメントの変換

変換とは、XMLドキュメント(変換元)を他の形式(変換結果)に変換することです。通常は、別のXMLドキュメント、HTML、無線用マークアップ言語(Wireless Markup Language : WML)などに変換されます。この節では、JAXPを使用して、およびJSP内からJSPタグを使用してXMLドキュメントを変換する方法について説明します。

JAXPによるXMLデータの変換

バージョン1.2のJAXPでは、プラガブルの変換が提供されています。つまり、JAXP準拠の任意のトランスフォーマ・エンジンを使用できます。

JAXPは、XMLデータを様々な形式に変換するために以下のインタフェースを提供します。

- javax.xml.transform
ドキュメントを変換するための汎用APIがあります。SAXかDOMかに関係なく、変換元および変換結果の形式を推測し、できる限り少ない候補に絞り込みます。

- javax.xml.transform.stream
ストリーム固有およびURI固有の変換APIを実装します。具体的には、InputStreamsとURLを変換元、OutputStreamsとURLを変換結果として指定できるStreamSourceクラスおよびStreamResultクラスが定義されています。

- javax.xml.transform.dom
DOM固有の変換APIを実装します。具体的には、DOMツリーを変換元か変換結果、またはその両方として指定できるDOMSourceクラスおよびDOMResultクラスが定義されています。

- javax.xml.transform.sax
SAX固有の変換APIを実装します。具体的には、org.xml.sax.ContentHandlerイベントを変換元か変換結果、またはその両方として指定できるSAXSourceクラスおよびSAXResultクラスが定義されています。

変換には、入力と出力の多くの組合せがあります。

JAXPによるXMLドキュメント変換の例

抜粋した次のサンプル・コードでは、JAXPを使用してmyXMLdoc.xmlを、mystylesheet.xslスタイルシートを使用する別のXMLドキュメントに変換する方法を示します。

import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.stream.StreamResult;

Transformer trans;
TransformerFactory factory = TransformerFactory.newInstance();
String stylesheet = "file://stylesheets/mystylesheet.xsl";
String xml_doc = "file://xml_docs/myXMLdoc.xml";

trans = factory.newTransformer(new StreamSource(stylesheet));
trans.transform(new StreamSource(xml_doc),
new StreamResult(System.out));

DomドキュメントをXMLストリームに変換する方法の例については、「JAXPによるXMLデータの変換」を参照してください。

JSPタグによるXMLデータの変換

WebLogic Serverでは、JSP内からXSLTトランスフォーマに簡単にアクセスするための小規模なJSPタグ・ライブラリが提供されます。このタグを使用するとXMLドキュメントをHTML、WMLなどに変換できます。

注意:

この機能はWebLogic Server 12.1.2.0で非推奨となり、将来のリリースでは削除される可能性があります。

JSPタグ・ライブラリは、メイン・タグのx:xsltと、x:xsltタグ内部で使用できる2つのサブタグ(x:stylesheetおよびx:xml)で構成されます。

注意:

JSPタグ・ライブラリは使い勝手を良くするために用意されているだけであり、JSP内からXSLTトランスフォーマへのアクセスに必須というわけではありません。

XSLT JSPタグ構文

XSLT JSPタグ構文はXMLを基にしています。JSPタグは、開始タグ、本文(オプション)、対応する終了タグで構成されます。開始タグには要素名と属性(オプション)が含まれます。

注意:

この機能はWebLogic Server 12.1.2.0で非推奨となり、将来のリリースでは削除される可能性があります。

次の構文では、WebLogic Serverで提供される3つのXSLT JSPタグをJSPで使用する方法について示します。属性は省略可能です。また、x:stylesheetおよびx:xmlサブタグも省略可能です。構文に続く表では、x:xsltおよびx:stylesheetタグの属性について示します。x:xmlタグには属性はありません。

<x:xslt  [xml="uri of XML file"]
[media="media type to determine stylesheet"]
[stylesheet="uri of stylesheet"]
<x:xml>In-line XML goes here
</x:xml>
<x:stylesheet [media="media type to determine stylesheet"]
[uri="uri of stylesheet"]
</x:stylesheet>
</x:xslt>

表3-1 x:xsltタグの属性を示します。

表3-1 x:xslt JSPタグの属性

x:xsltタグの属性

必須

データ型

説明

xml

いいえ

String

変換するXMLファイルの場所を指定します。場所は、タグが使用されるWebアプリケーションのドキュメント・ルートへの相対パス。

media

いいえ

String

HTMLまたはWMLなど、ドキュメントの出力タイプを定義します。このタイプによって、XMLドキュメントの変換時に使用するスタイルシートが決定されます。

この属性は、x:xsltタグ本文内のx:stylesheetタグで囲まれたmedia属性と組み合せて使用できます。x:xsltタグのmedia属性の値はx:stylesheetタグに囲まれたmedia属性の値と比較されます。値が等しい場合、x:stylesheetタグのuri属性で指定されたスタイルシートがXMLドキュメントに適用されます。

注意: 同じx:xsltタグ内でmediaおよびstylesheet属性の両方を設定するのは誤りです。

stylesheet

いいえ

String

XMLドキュメントの変換に使用するスタイルシートの場所を指定します。場所は、タグが使用されるWebアプリケーションのドキュメント・ルートへの相対パス。

注意: 同じx:xsltタグ内でmediaおよびstylesheet属性の両方を設定するのは誤りです。

表3-2 x:stylesheetタグの属性について説明します。

表3-2 x:stylesheet JSPタグの属性

x:stylesheetタグの属性

必須

データ型

説明

media

いいえ

String

HTMLまたはWMLなど、ドキュメントの出力タイプを定義します。このタイプによって、XMLドキュメントの変換時に使用するスタイルシートが決定されます。

この属性はx:xsltタグに囲まれたmedia属性と組み合せて使用します。x:xsltタグのmedia属性の値はx:stylesheetタグに囲まれたmedia属性の値と比較されます。値が等しい場合、x:stylesheetタグのuri属性で指定されたスタイルシートがXMLドキュメントに適用されます。

uri

いいえ

String

media属性の値が、x:xsltタグに囲まれたmedia属性の値と一致する場合に使用するスタイルシートの場所を指定します。場所は、タグが使用されるWebアプリケーションのドキュメント・ルートへの相対パス。

XSLT JSPタグの使い方

x:xsltタグは本文の有無に関わらず使用でき、属性は省略可能です。この節では、本文や1つまたは複数の属性を指定したかどうかによってタグの動作を決定するルールについて説明します。

注意:

この機能はWebLogic Server 12.1.2.0で非推奨となり、将来のリリースでは削除される可能性があります。

x:xslt JSPタグが空タグ(本文なし)の場合、以下の説明が適用されます。

- 属性が設定されていない場合、XMLドキュメントはサーブレットのパスとデフォルトのメディア・スタイルシートで処理されます。XMLファイルで、<?xml-stylesheet>処理指示を使用してデフォルトのメディア・スタイルシートを指定します。デフォルトのスタイルシートにはmedia属性はありません。
この処理のタイプでは、XSLT処理を実行するファイル・サーブレットとしてタグ拡張を含むJSPページを登録できます。

- media属性のみが設定されている場合、XMLドキュメントは、サーブレットのパスと指定されたメディア・タイプを使用して処理されます。x:xsltタグのmediaタイプ属性の値は、XMLドキュメントにある<?xml-stylesheet>処理指示のmedia属性の値と比較されます。一致した場合は対応するスタイルシートが適用されます。一致しない場合はデフォルトのメディア・スタイルシートが使用されます。メディア・タイプ属性は、ドキュメントの出力タイプ(XML、HTML、ポストスクリプト、WMLなど)の定義に使用します。この機能を使用すると、ドキュメントの出力タイプごとにスタイルシートをまとめることができます。

- xml属性のみが設定されている場合、指定したXMLドキュメントはデフォルトのメディア・スタイルシートで処理されます。

- mediaおよびxml属性を設定すると、指定したXMLドキュメントは指定したメディア・タイプを使用して処理されます。

- stylesheet属性が定義されている場合、XMLドキュメントは指定したスタイルシートで処理されます。

注意:

同じx:xsltタグ内でmedia属性とstylesheet属性の両方を設定するとエラーが発生します。

本文があるXSLT JSPタグは、<x:xml>タグまたは<x:stylesheet>タグを含んでいる場合があります。以下の説明が適用されます。

- <x:xml>タグを使用すると、XMLドキュメントをインライン処理用に指定できます。このタグには属性はありません。

- <x:stylesheet>タグは、属性を指定しない場合、デフォルトのスタイルシートをインラインで指定できます。

- <x:stylesheet>タグのuri属性を使用して、デフォルト・スタイルシートの場所を指定します。

- 様々なメディア・タイプごとに異なるスタイルシートを指定する場合は、media属性に異なる値を指定して、複数の<x:stylesheet>タグを使用できます。タグの本文でメディア・タイプごとのスタイルシートを指定したり、uri属性を使ってスタイルシートの場所を指定したりできます。

XSLT JSPタグによるXMLドキュメントの変換

XSLT JSPタグでXMLドキュメントを変換するには、以下の手順を実行します。

注意:

この機能はWebLogic Server 12.1.2.0で非推奨となり、将来のリリースでは削除される可能性があります。

1. WL_HOME/server/extディレクトリのxmlx.zipファイルを開いて、xmlx-tags.jarファイルをWebアプリケーションの/libディレクトリに移動します。WL_HOMEは、WebLogic Server配布をインストールした最上位ディレクトリです。

2. <taglib>エントリをweb.xmlファイルに追加します。例:

<taglib>
<taglib-uri>xmlx.tld</taglib-uri>
<taglib-location>/WEB-INF/lib/xmlx-tags.jar</taglib-location>
</taglib>

3. タグを使用するには、次の行をJSPページに追加します。

<%@ taglib uri="xmlx.tld" prefix="x"%>

4. トランスフォーマを構成します。以下の手順では、トランスフォーマの構成の一般的な方法を示します。

1. 次のコード行を入力してxslt.jspファイルを作成します。

<%@ taglib uri="xmlx.tld" prefix="x"%><x:xslt/>

2. 次のように、xslt.jspファイルをweb.xmlファイルに登録します。

<servlet>
<servlet-name>myxsltinterceptor</servlet-name>
<jsp-file>xslt.jsp</jsp-file>
</servlet>
<servlet-mapping>
<servlet-name>myxsltinterceptor</servlet-name>
<url-pattern>/xslt/*</url-pattern>
</servlet-mapping>

3. XML、DTD、XSLドキュメントまたはサーブレットをWebアプリケーションに配置します。

4. xslt接頭辞をXMLドキュメントのパス名に追加(たとえば、docs/fred.xmlをxslt/docs/fred.xmlに変更)し、ドキュメントにアクセスします。web.xmlファイルの<url-pattern>エントリによって、WebLogic Serverは、XMLドキュメントに対して自動的にXSLTトランスフォーマを実行し、ドキュメントにデフォルトのスタイルシートを設定します。

5. メディア・タイプを定義するには、XMLドキュメントのメディア・タイプと出力のコンテンツ・タイプを指定するコードをJSPに追加します。

6. メディア・タイプをxsltタグに渡して、応答オブジェクトのコンテンツ・タイプを設定します。

注意:

他の形のXSLT JSPタグは、スタイルシートがXMLドキュメントで指定されていない場合またはXMLスタイルシートがインラインで生成される場合に使用されます。

JSPでのXSLT JSPタグの使用例

JSPから抜粋した次のコードは、XSLT JSPタグを使用し、JSPを要求するクライアントのタイプに従って、XMLをHTMLまたはWMLに変換する方法を示します。JSPは、クライアントがブラウザの場合はHTMLを返し、無線デバイスの場合はWMLを返します。

注意:

この機能はWebLogic Server 12.1.2.0で非推奨となり、将来のリリースでは削除される可能性があります。

最初に、JSPはHttpServletRequestオブジェクトのgetHeader()メソッドを使用して、JSPを要求するクライアントのタイプを判別します。次に、myMedia変数を wmlまたはhtmlに適切に設定します。JSPでmyMedia変数をhtmlに設定した場合は、content変数に含まれるXMLドキュメントにhtml.xslスタイルシートが適用されます。同様に、JSPでmymedia変数をwmlに設定した場合は、wml.xslスタイルシートが適用されます。

<%
String clientType = request.getHeader("User-Agent");
// default to WML client
String myMedia = "wml";

// if client is an HTML browser

if (clientType.indexOf("Mozilla") != -1) {
myMedia = "http"
}
%>

<x:xslt media="<%=myMedia%>">
<x:xml><%=content%></x:xml>
<x:stylesheet media="html" uri="html.xsl"/>
<x:stylesheet media="wml"  uri="wml.xsl"/>
</x:xslt>

デフォルト・トランスフォーマ以外のトランスフォーマの使い方

WebLogic ServerのXMLレジストリ(管理コンソールで構成)では、以下の項目を構成します。

- デフォルト・トランスフォーマをサーバー全体のトランスフォーマとして使用します。

- デフォルト・トランスフォーマ以外のトランスフォーマをサーバー全体のトランスフォーマとして使用します。トランスフォーマはJAXP準拠でなくてはなりません。

Xmlレジストリで変換オプションを構成する手順については、「デフォルト以外のパーサーまたはトランスフォーマの構成」を参照してください。

4 Streaming API for XML (StAX)の使い方

この章では、Streaming API for XML (StAX)によりXMLドキュメントの解析と生成を行う方法について説明します。

この章の内容は以下のとおりです。

- Streaming API for XMLの概要

- XMLStreamReaderインタフェースによるXMLの解析:一般的な手順

- XMLStreamWriterインタフェースによるXMLの生成:一般的な手順

- XMLInputFactoryインタフェース用に定義されたプロパティ

- XMLOutputFactoryインタフェース用に定義されたプロパティ

Streaming API for XMLの概要

Java Community ProcessのJSR-173 (http://www.jcp.org/en/jsr/detail?id=173)で定義されているStreaming API for XML (StAX)を使用すると、XMLドキュメントを簡単かつ直感的に解析および生成できます。SAX APIと似ていますが、XMLドキュメントに対する手続き的なストリーム・ベースの処理が可能であり、SAXイベント・ハンドラを作成する必要はありません。SAXイベント・ハンドラで複雑なXMLドキュメントを扱うと、ハンドラ自体が複雑になる場合があります。つまり、StAXを利用すれば、SAXよりきめ細かく解析を制御できます。

SAXを使用してXMLドキュメントを解析する場合、プログラムでは、イベント発生時に解析をリスニングするイベント・リスナーを作成し、特定のイベントを請求するのではなくイベントに対して対応する必要があります。一方、StAXを使用する場合は、XMLドキュメントを手順の流れに沿って処理すること、特定のタイプのイベント(要素の開始など)を請求すること、要素の属性を繰返し処理すること、ドキュメントの先頭をスキップすること、任意の時点で処理を停止すること、特定の要素の下位要素を取得すること、指定どおりに要素をフィルタ処理することができます。イベントに対応するのではなく、イベントを請求するので、StAXを使用する方法は、プル解析と呼ばれることもあります。

StAXには、カーソルAPIとイベント・イテレータAPIという2つのAPIがあり、どちらでもXMLを読み書きできます。以下の節では、各APIおよびそれぞれの利点について説明します。

カーソルAPIの説明

カーソルAPIの基本機能は、できる限り簡単かつ効率的にXMLを解析および生成できるようにするためのものです。StAXの2つのAPIのうち、ほとんどのプログラマが使用すると思われるのは、こちらの方です。

カーソルAPIは、開始要素、コメント、属性などの一連のイベントを、発生していないものも含めて繰返し処理します。カーソルAPIには、XML解析用のXMLStreamReaderとXML生成用のXMLStreamWriterという2つの主要なインタフェースがあります。

XMLStreamReaderインタフェース

カーソルAPIは、XMLStreamReaderインタフェースを使用して仮想カーソルをXMLドキュメント上に移動し、hasNext()、next()、getEventType()、およびgetText()などのメソッドを呼び出してデータおよび基底の状態にアクセスできるようにします。XMLStreamReaderインタフェースでは、XMLに対して読取り専用の前方アクセスのみが可能です。

XMLStreamReaderの新しいインスタンスを作成するには、XMLInputFactoryクラスを使用します。新しいリーダー を取得すると、様々なプロパティを設定できます。詳細は、「XMLInputFactoryインタフェース用に定義されたプロパティ」を参照してください。

XMLStreamReaderインタフェースのnext()メソッドを使用してXMLを解析すると、リーダーは次の解析イベントを取得し、読み込んだイベントの種類を識別する整数を返します。解析イベントは、XML宣言、開始要素タグ、終了要素タグ、ホワイトスペース、コメント、処理手順などのXMLドキュメントの各セクションに対応します。XMLStreamConstantインタフェースは、next()メソッドによって返された整数に対応するイベントを指定します。XMLStreamReaderのgetEventType()メソッドを使用して、イベントの種類を判別することもできます。

XMLStreamReaderインタフェースには、XMLドキュメントの特定のデータを取得するための様々なメソッドがあります。そのメソッドの一部を次に示します。

- getLocalName() - 現在のイベントのローカル名を返します。

- getPrefix() - 現在のイベントの接頭辞を返します。

- getAttributeXXX() - 現在の属性イベントに関する情報を返す一連のメソッドです。

- getNamespaceXXX() - 現在のネームスペース・イベントに関する情報を返す一連のメソッドです。

- getTextXXX() - 現在のテキスト・イベントに関する情報を返す一連のメソッドです。

- getPIData() - 現在の処理手順イベントのデータ・セクションを返します。

有効なメソッドは、イベントの種類ごとに決まっています。無効なイベントの種類でメソッドを呼び出そうとすると、StAXプロセッサからjava.lang.IllegalStateExceptionが送出されます。たとえば、ネームスペース・イベントでgetAttributeXXX()メソッドを呼び出すとエラーになります。イベントの完全なリストとそのイベントで有効なXMLStreamReaderメソッドについては、http://www.jcp.org/en/jsr/detail?id=173にあるStAX仕様を参照してください。

XMLStreamWriterインタフェース

カーソルAPIは、XMLStreamWriterインタフェースを使用して、XMLの生成方法を指定します。

XMLStreamWriterの新しいインスタンスを作成するには、XMLOutputFactoryクラスを使用します。新しいライターを取得すると、ネームスペースおよび接頭辞を修正するためのプロパティを設定できます。詳細は、「XMLOutputFactoryインタフェース用に定義されたプロパティ」を参照してください。

XMLStreamWriterインタフェースには、XMLドキュメントの標準的な部分に書込みを行う一連のwriteXXX()メソッドが定義されています。以下に、そのメソッドを示します。

- writeStartElement()

- writeEndDocument()

- writeAttribute()

- writeNamespace()

- writeCData()

属性とネームスペースを含むXMLドキュメントの各部分は、これらのメソッドによって明示的に書き込まれます。

キャッシュされたデータを出力に書き込むにはflush()メソッド、ライターを閉じてリソースを解放するにはclose()メソッドを使用します。

XMLStreamWriterは、XMLの生成時に、生成されたドキュメントが整形式かどうかをチェックしません。整形式のXMLドキュメントを作成するのは、プログラマの役目です。特殊文字&、<、および>を出力するには、writeCharacters()メソッドを使用します。

イベント・イテレータAPIの説明

イベント・イテレータAPIは、カーソルAPIのすぐ上のレイヤーです。パイプライニングの拡張および促進を簡単に行うことができます。パイプライニングとは、複数のXML間の変換のことです。イベント・イテレータAPIを使用すると、パイプラインの各ステージでXMLをデシリアライズおよびシリアライズする必要はなくなり、パイプラインの両端でのみnextEvent()などのAPIメソッドを使用して中間ステージで通信します。イベント・イテレータAPIには、XML解析用のXMLEventReaderとXML生成用のXMLEventWriterという2つの主要なインタフェースがあります。

カーソルAPIがStAXで最も頻繁に使用されるAPIなので、このセクションではイベント・イテレータAPIの詳細な使い方については例を挙げる他には説明しません。このAPIの詳細な使い方については、StAX仕様(http://www.jcp.org/en/jsr/detail?id=173)を参照してください。

次の例では、StAXのXMLEventReaderインタフェースを使用してXMLドキュメントを解析する単純なプログラムを示します。このプログラムは、XMLファイルを表す1つのパラメータを取り、それを使用してXMLEventReaderオブジェクトを作成します。次に、リーダーを使用して、イベントのストリームを繰返し処理して出力します。

package examples.event;

import java.io.FileReader;
import javax.xml.stream.*;
import javax.xml.stream.events.*;
import javax.xml.stream.util.*;
import javax.xml.namespace.QName;

/**
* A simple example to iterate over events
*
* @author Copyright (c) 2002 by BEA Systems. All Rights Reserved.
*/

public class Parse {
private static String filename = null;
private static void printUsage() {
System.out.println("usage: java examples.event.Parse <xmlfile>");
}

public static void main(String[] args) throws Exception {
try {
filename = args[0];
} catch (ArrayIndexOutOfBoundsException aioobe){
printUsage();
System.exit(0);
}

XMLInputFactory factory = XMLInputFactory.newInstance();
XMLEventReader r =
factory.createXMLEventReader(new FileReader(filename));
while(r.hasNext()) {
XMLEvent e = r.nextEvent();
System.out.println("ID:"+e.hashCode()+"["+e+"]");
}
}
}

StAXのメイン・インタフェースとクラス

表4-1で、Streaming API for XMLの主なインタフェースとクラスについて説明します。

表4-1 Streaming API for XMLの主なインタフェースとクラス

インタフェースまたはクラス

カーソルAPI用/イベント・イテレータAPI用

説明

XMLInputFactory class

両方

XMLStreamReaderまたはXMLEventReaderインスタンスの作成に使用するファクトリ・クラス。

XMLOutputFactory class

両方

XMLStreamWriterまたはXMLEventWriterインスタンスの作成に使用するファクトリ・クラス。

XMLEventFactory class

イベント・イテレータ

XMLEventインスタンスの作成に使用するファクトリ・クラス。

XMLStreamReader interface

カーソル

XMLドキュメントの解析に使用するインタフェース。次のイベントを参照および取得し、それ以降のイベントがあるかどうかをチェックできます。

XMLStreamWriter interface

カーソル

XMLドキュメントの生成に使用するインタフェース。開始要素や属性など、XMLドキュメントの特定の部分を生成する一連のwriteXXX()メソッドを利用できます。

XMLEventReader interface

イベント・イテレータ

XMLイベントの解析に使用するインタフェース。次のイベントを参照および取得し、それ以降のイベントがあるかどうかをチェックできます。

XMLEventWriter interface

イベント・イテレータ

XMLの生成に使用するインタフェース。add()メソッドを使用して出力ストリームにXMLEventsを追加します。

XMLEvent

イベント・イテレータ

イベントを処理する基本インタフェース。StartElementやAttributeなど、XMLEventから拡張された特定の全XMLイベント。

XMLStreamException exception

両方

整形式のXMLドキュメント構造の欠陥など、予期しない処理エラーに関する基底の例外。

XMLStreamReaderインタフェースによるXMLの解析:一般的な手順

以下の手順は、StAXカーソルAPIのXMLStreamReaderインタフェースによりXMLドキュメントの解析を行う一般的手順について説明したものです。この手順では、「StAXを使用したXML解析の例」で示すサンプル・コードを用います。

1. javax.xml.stream.*クラスをインポートします。

2. 次のコードの抜粋で示すように、XMLInputFactory.newInstance()メソッドを使用してXMLInputFactoryをインスタンス化します。

XMLInputFactory xmlif = XMLInputFactory.newInstance();

設定可能なプロパティのリストについては、「XMLInputFactoryインタフェース用に定義されたプロパティ」を参照してください。

3. XMLドキュメントを基に、XMLInputFactory.createXMLStreamReader()メソッドを使用してXMLStreamReaderオブジェクトをインスタンス化します。
詳細は、「XMLStreamReaderオブジェクトの取得」を参照してください。

4. 次のコードの抜粋で示すように、hasNext()メソッドとnext()メソッドで各XMLイベントを順番に処理してXMLドキュメントを解析します。

while(xmlr.hasNext()){
printEvent(xmlr);
xmlr.next();

この例では、xmlrがXMLStreamReaderインスタンスに当たり、ローカル・メソッドprintEvent() (StAX APIの一部ではありません)が、次の手順に示すように特定のイベント・タイプを判別します。

5. XMLドキュメントの解析中に、現在の特定のイベント・タイプを判別し、それに対応した処理を行います。イベント・タイプには、XMLドキュメントの開始と終了、XML要素の開始と終了、コメント、エンティティ参照などがあります。
「特定のXMLイベント・タイプの判別」を参照してください。

6. 現在のイベント・タイプが開始要素または終了要素の場合、必要に応じてその属性を取得します。
「要素の属性の取得」を参照してください。

7. 現在のイベント・タイプが開始要素または終了要素の場合、必要に応じてそのネームスペースを取得します。
「要素のネームスペースの取得」参照してください。

8. 現在のイベント・タイプにCDATAやコメントなどのテキスト・データが含まれる場合、必要に応じて実際のデータを取得します。
「テキスト・データの取得」を参照してください。

9. 必要に応じて、行番号や列番号など、現在のイベントの場所の情報を取得します。
「場所の情報の取得」を参照してください。

10. ストリームをクローズします。
「入力ストリームのクローズ」を参照してください。

StAXを使用したXML解析の例

次の例では、StAXのXMLStreamReaderインタフェースを使用してXMLドキュメントを解析する単純なプログラムを示します。

このプログラムは、XMLファイルを表す1つのパラメータを取り、それを使用してXMLStreamReaderオブジェクトを作成します。次に、リーダーを使用してイベントのストリームを繰返し処理し、XML要素の開始、要素の属性のリスト、処理手順など、各イベントのタイプを判別します。このサンプル・プログラムは、内部メソッドを使用して、適切な場合は属性およびネームスペースのリストを出力し、これらのイベントに関する情報を出力します。

太字のコードは、以降の節で説明します。

package examples.basic;

import java.io.FileReader;
import java.util.Iterator;
import javax.xml.stream.*;
import javax.xml.namespace.QName;

/**
* This is a simple parsing example that illustrates
* the XMLStreamReader class.
*
* @author Copyright (c) 2003 by BEA Systems. All Rights Reserved.
*/

public class Parse {
private static String filename = null;
private static void printUsage() {
System.out.println("usage: java examples.basic.Parse <xmlfile>");
}

public static void main(String[] args) throws Exception {
try {
filename = args[0];
} catch (ArrayIndexOutOfBoundsException aioobe){
printUsage();
System.exit(0);
}

//
// Get an input factory
//
XMLInputFactory xmlif = XMLInputFactory.newInstance();
System.out.println("FACTORY: " + xmlif);

//
// Instantiate a reader
//
XMLStreamReader xmlr = xmlif.createXMLStreamReader(new FileReader(filename));
System.out.println("READER:  " + xmlr + "\n");

//
// Parse the XML
//
while(xmlr.hasNext()){
printEvent(xmlr);
xmlr.next();
}

//
// Close the reader
//
xmlr.close();

}

private static void printEvent(XMLStreamReader xmlr) {

System.out.print("EVENT:["+xmlr.getLocation().getLineNumber()+"]["+
xmlr.getLocation().getColumnNumber()+"] ");

System.out.print(" [");
switch (xmlr.getEventType()) {

case XMLStreamConstants.START_ELEMENT:
System.out.print("<");
printName(xmlr);
printNamespaces(xmlr);
printAttributes(xmlr);
System.out.print(">");
break;
case XMLStreamConstants.END_ELEMENT:
System.out.print("</");
printName(xmlr);
System.out.print(">");
break;
case XMLStreamConstants.SPACE:
case XMLStreamConstants.CHARACTERS:
int start = xmlr.getTextStart();
int length = xmlr.getTextLength();
System.out.print(new String(xmlr.getTextCharacters(),
start,
length));
break;

case XMLStreamConstants.PROCESSING_INSTRUCTION:
System.out.print("<?");
if (xmlr.hasText())
System.out.print(xmlr.getText());
System.out.print("?>");
break;

case XMLStreamConstants.CDATA:
System.out.print("<![CDATA[");
start = xmlr.getTextStart();
length = xmlr.getTextLength();
System.out.print(new String(xmlr.getTextCharacters(),
start,
length));
System.out.print("]]>");
break;

case XMLStreamConstants.COMMENT:
System.out.print("<!--");
if (xmlr.hasText())
System.out.print(xmlr.getText());
System.out.print("-->");
break;

case XMLStreamConstants.ENTITY_REFERENCE:
System.out.print(xmlr.getLocalName()+"=");
if (xmlr.hasText())
System.out.print("["+xmlr.getText()+"]");
break;

case XMLStreamConstants.START_DOCUMENT:
System.out.print("<?xml");
System.out.print(" version='"+xmlr.getVersion()+"'");
System.out.print(" encoding='"+xmlr.getCharacterEncodingScheme()+"'");
if (xmlr.isStandalone())
System.out.print(" standalone='yes'");
else
System.out.print(" standalone='no'");
System.out.print("?>");
break;

}
System.out.println("]");
}

private static void printName(XMLStreamReader xmlr){
if(xmlr.hasName()){
String prefix = xmlr.getPrefix();
String uri = xmlr.getNamespaceURI();
String localName = xmlr.getLocalName();
printName(prefix,uri,localName);
}
}

private static void printName(String prefix,
String uri,
String localName) {
if (uri != null && !("".equals(uri)) ) System.out.print("['"+uri+"']:");
if (prefix != null) System.out.print(prefix+":");
if (localName != null) System.out.print(localName);
}

private static void printAttributes(XMLStreamReader xmlr){
for (int i=0; i < xmlr.getAttributeCount(); i++) {
printAttribute(xmlr,i);
}
}

private static void printAttribute(XMLStreamReader xmlr, int index) {
String prefix = xmlr.getAttributePrefix(index);
String namespace = xmlr.getAttributeNamespace(index);
String localName = xmlr.getAttributeLocalName(index);
String value = xmlr.getAttributeValue(index);
System.out.print(" ");
printName(prefix,namespace,localName);
System.out.print("='"+value+"'");
}

private static void printNamespaces(XMLStreamReader xmlr){
for (int i=0; i < xmlr.getNamespaceCount(); i++) {
printNamespace(xmlr,i);
}
}

private static void printNamespace(XMLStreamReader xmlr, int index) {
String prefix = xmlr.getNamespacePrefix(index);
String uri = xmlr.getNamespaceURI(index);
System.out.print(" ");
if (prefix == null)
System.out.print("xmlns='"+uri+"'");
else
System.out.print("xmlns:"+prefix+"='"+uri+"'");
}
}

XMLStreamReaderオブジェクトの取得

次のコードの抜粋で示すように、XMLInputFactory.createXMLStreamReader()メソッドを使用し、XMLドキュメントに基づいてXMLStreamReaderオブジェクトをインスタンス化します。

XMLStreamReader xmlr = xmlif.createXMLStreamReader(new FileReader(filename));

この例では、xmlifがXMLInputFactoryインスタンスに当たります。

createXMLStreamReader()メソッドの様々なシグネチャにより、以下のXMLドキュメント・フォーマットをパラメータとして扱うことができます。

- java.io.InputStream

- java.io.Reader (例で示します)

- javax.xml.transform.Source (JAXP API http://docs.oracle.com/javase/6/docs/technotes/guides/xml/index.htmlで指定)

特定のXMLイベント・タイプの判別

XMLドキュメントの解析中に特定のイベント・タイプを判別するには、XMLStreamReader.next()メソッドまたはXMLStreamReader.getEventType()メソッドを使用します。next()メソッドは、次のイベントを読み込んで、そのイベント・タイプを示す整数を返し、getEventType()メソッドは、現在のイベント・タイプを示す整数を単純に返します。XMLStreamReaderのXMLStreamConstants上位インタフェースには、以下のリストに示すイベント・タイプ定数が定義されています。

- XMLStreamConstants.ATTRIBUTE

- XMLStreamConstants.CDATA

- XMLStreamConstants.CHARACTERS

- XMLStreamConstants.COMMENT

- XMLStreamConstants.DTD

- XMLStreamConstants.END_DOCUMENT

- XMLStreamConstants.END_ELEMENT

- XMLStreamConstants.ENTITY_DECLARATION

- XMLStreamConstants.ENTITY_REFERENCE

- XMLStreamConstants.NAMESPACE

- XMLStreamConstants.NOTATION_DECLARATION

- XMLStreamConstants.PROCESSING_INSTRUCTION

- XMLStreamConstants.SPACE

- XMLStreamConstants.START_DOCUMENT

- XMLStreamConstants.START_ELEMENT

次の例では、Java case文を使用して、XMLStreamReader.next()メソッドから返されたイベントのタイプを判別する方法を示します。この例では、XMLStreamReader.getEventType()メソッドを使用して、next()メソッドから返された整数値を基に現在のイベント・タイプを判別します。簡単にするため、この例では、見つかったイベントをそのまま出力します。イベントをさらに処理する方法は、その後の節で示します。

switch (xmlr.getEventType()) {

case XMLStreamConstants.START_ELEMENT:
System.out.print("Start Element\n");
break;

case XMLStreamConstants.END_ELEMENT:
System.out.print("End Element\n");
break;

case XMLStreamConstants.SPACE:
System.out.print("Space\n");
break;

case XMLStreamConstants.CHARACTERS:
System.out.print("Characters\n");
break;

case XMLStreamConstants.PROCESSING_INSTRUCTION:
System.out.print("Processing Instrcutions\n");
break;

case XMLStreamConstants.CDATA:
System.out.print("CDATA\n");
break;

case XMLStreamConstants.COMMENT:
System.out.print("Comment\n");
break;

case XMLStreamConstants.DTD:
System.out.print("DTD\n");
break;

case XMLStreamConstants.ENTITY_REFERENCE:
System.out.print("Entity Reference\n");
break;

case XMLStreamConstants.ENTITY_DECLARATION:
System.out.print("Entity Declaration\n");
break;

case XMLStreamConstants.START_DOCUMENT:
System.out.print("Start Document\n");
break;

case XMLStreamConstants.END_DOCUMENT:
System.out.print("End Document\n");
break;

}

完全な要素名の取得

完全な要素名には、接頭辞、ネームスペースURI、ローカル名が含まれます。現在のイベントが開始要素または終了要素であることを判別したら、XMLStreamReaderインタフェースのgetPrefix()メソッド、getNamespaceURI()メソッド、およびgetLocalName()メソッドをそれぞれ使用して、この情報を取得します。

たとえば、サンプル・プログラムで、開始イベント要素のcase文が次のようになっているとします。

case XMLStreamConstants.START_ELEMENT:

System.out.print("<");
printName(xmlr);
printNamespaces(xmlr);
printAttributes(xmlr);
System.out.print(">");
break;

注意:

printNamespaces()メソッドとprintAttributes()メソッドについては、別の節で説明します。

2つのprintName()ローカル・メソッドは、次のようにgetXXX()メソッドを使用できます。

private static void printName(XMLStreamReader xmlr){
if(xmlr.hasName()){
String prefix = xmlr.getPrefix();
String uri = xmlr.getNamespaceURI();
String localName = xmlr.getLocalName();
printName(prefix,uri,localName);
}
}

private static void printName(String prefix,
String uri,
String localName) {
if (uri != null && !("".equals(uri)) ) System.out.print("['"+uri+"']:");
if (prefix != null) System.out.print(prefix+":");
if (localName != null) System.out.print(localName);
}

要素の属性の取得

現在のイベントが開始要素、終了要素、または属性であることを判別したら、XMLStreamReaderインタフェースのgetAttributeXXX()メソッドを使用して、属性とその値のリストを取得します。

注意:

getAttributeXXX()メソッドを使用できるのは、開始要素、終了要素、属性イベントに対してのみです。それ以外のタイプのイベントでこのメソッドを実行しようとすると、java.lang.IllegalStateExceptionが送出されます。

getAttributeCount()メソッドを使用すると、現在の要素の属性数を取得し、属性のリストに対して反復処理を行うループでその属性数を使用することができます。メソッドは、ネームスペースをこの数には含みません。追加のgetAttributeXXX()メソッドは、特定の属性の接頭辞、ネームスペースURI、ローカル名、および値を返します。

たとえば、サンプル・プログラムで、開始イベント要素のcase文が次のようになっているとします。

case XMLStreamConstants.START_ELEMENT:

System.out.print("<");
printName(xmlr);
printNamespaces(xmlr);
printAttributes(xmlr);
System.out.print(">");
break;

注意:

printName()メソッドとprintNamespaces()メソッドについては、別の節で説明します。

次のローカル・メソッドprintAttributes()では、属性のリストに対して反復処理を行う方法を示します。属性索引はゼロベースなので、forループは0から始まります。

private static void printAttributes(XMLStreamReader xmlr){

for (int i=0; i < xmlr.getAttributeCount(); i++) {
printAttribute(xmlr,i);
}
}

次のローカル・メソッドprintAttribute()では、特定の属性の全情報を出力する方法を示します。

private static void printAttribute(XMLStreamReader xmlr, int index) {
String prefix = xmlr.getAttributePrefix(index);
String namespace = xmlr.getAttributeNamespace(index);
String localName = xmlr.getAttributeLocalName(index);
String value = xmlr.getAttributeValue(index);
System.out.print(" ");
printName(prefix,namespace,localName);
System.out.print("='"+value+"'");
}

printName()メソッドについては、「完全な要素名の取得」で説明しています。

要素のネームスペースの取得

現在のイベントが開始要素、終了要素、またはネームスペースであることを判別したら、XMLStreamReaderインタフェースのgetNamespaceXXX()メソッドを使用して、イベント用に宣言されたネームスペースのリストを取得します。

注意:

getNamespaceXXX()メソッドを使用できるのは、開始要素、終了要素、ネームスペース・イベントに対してのみです。それ以外のタイプのイベントでこのメソッドを実行しようとすると、java.lang.IllegalStateExceptionが送出されます。

getNamespaceCount()メソッドを使用すると、現在のイベント用に宣言されているネームスペースの数を返し、そのリストに対して反復処理を行うループでそのネームスペース数を使用することができます。現在のイベントが終了要素の場合、この数は、スコープ外になるネームスペースの数を示します。追加のgetNamespaceXXX()メソッドは、特定のネームスペースの接頭辞とネームスペースURIを返します。

たとえば、サンプル・プログラムで、開始イベント要素のcase文が次のようになっているとします。

case XMLStreamConstants.START_ELEMENT:

System.out.print("<");
printName(xmlr);
printNamespaces(xmlr);
printAttributes(xmlr);
System.out.print(">");
break;

注意:

printName()メソッドとprintAttributes()メソッドについては、別の節で説明します。

次のローカル・メソッドprintNamespaces()では、開始要素のネームスペースのリストに対して反復処理を行う方法を示します。ネームスペース索引はゼロベースなので、forループは0から始まります。

private static void printNamespaces(XMLStreamReader xmlr){
for (int i=0; i < xmlr.getNamespaceCount(); i++) {
printNamespace(xmlr,i);
}
}

次のローカル・メソッドprintNamespace()では、特定のネームスペースの全情報を出力する方法を示します。

private static void printNamespace(XMLStreamReader xmlr, int index) {
String prefix = xmlr.getNamespacePrefix(index);
String uri = xmlr.getNamespaceURI(index);
System.out.print(" ");
if (prefix == null)
System.out.print("xmlns='"+uri+"'");
else
System.out.print("xmlns:"+prefix+"='"+uri+"'");
}

デフォルトのネームスペース宣言の場合、getNamespacePrefix()メソッドはnullを返します。

テキスト・データの取得

XMLStreamReaderインタフェースには、コメントやCDATAなどのイベントからテキスト・データを取得するための様々なgetTextXXX()メソッドが用意されています。

getTextStart()メソッドを使用して、現在のテキスト・イベントの最初の文字が格納されているテキスト文字配列内にオフセットを取得します。getTextLength()メソッドを使用して、テキスト文字配列内の文字列の長さを取得します。最後に、getTextCharacters()メソッドを使用して、現在のイベントのこの文字配列を返します。文字配列には、現在のイベントのみに関するテキスト情報が含まれています。next()メソッドを呼び出すと、入力ストリームの次のイベントがすぐに読み込まれ、文字配列に新しい情報が格納されます。

次の例では、CDATAイベントのテキスト・データを出力する方法を示します。

case XMLStreamConstants.CDATA:
System.out.print("<![CDATA[");
start = xmlr.getTextStart();
length = xmlr.getTextLength();
System.out.print(new String(xmlr.getTextCharacters(),
start,
length));
System.out.print("]]>");
break;

文字イベントに実際にテキストがあることを最初にチェックする場合は、次の例に示すようにhasText()メソッドを使用します。

case XMLStreamConstants.COMMENT:
System.out.print("<!--");
if (xmlr.hasText())
System.out.print(xmlr.getText());
System.out.print("-->");
break;

場所の情報の取得

StAX APIのLocationインタフェースでは、解析対象のXMLのパブリックIDやシステムIDとともに、行番号や列番号などイベントに関する場所の情報を取得するためのメソッドを利用できます。次の例に示すように、XMLStreamReaderインタフェースのgetLocation()メソッドを使用して、現在のイベントのLocationオブジェクトを返します。

System.out.print("EVENT:["+xmlr.getLocation().getLineNumber()+"]["+
xmlr.getLocation().getColumnNumber()+"] ");

入力ストリームのクローズ

プログラミング慣行として、作業終了時にXMLStreamReaderを明示的にクローズしてリソースを解放します。リーダーをクローズするには、XMLStreamReader.close()メソッドを使用します。以下に例を示します。

//
// Close the reader
//
xmlr.close();

XMLStreamWriterインタフェースによるXMLの生成:一般的な手順

以下の手順は、StAXカーソルAPIのXMLStreamWriterインタフェースにより、新しいXMLドキュメントの生成を行う一般的手順について説明したものです。

1. javax.xml.stream.*クラスをインポートします。

2. XMLOutputFactory.newInstance()メソッドを使用してXMLOutputFactoryをインスタンス化します。次に例を示します。

XMLOutputFactory xmlof = XMLOutputFactory.newInstance();

設定可能なプロパティのリストについては、「XMLOutputFactoryインタフェース用に定義されたプロパティ」を参照してください。

3. XMLOutputFactory.createXMLStreamWriter()メソッドを使用して、XMLを含むファイルまたはオブジェクトの名前を渡し、XMLStreamWriterオブジェクトをインスタンス化します。
詳細は、「XMLStreamWriterオブジェクトの取得」を参照してください。

4. XML宣言を出力に追加します。「出力ストリームへのXML宣言の追加」を参照してください。

5. 開始要素、コメント、文字などの標準XMLオブジェクトを出力に追加します。「出力ストリームへの標準XMLイベントの追加」を参照してください。

6. 属性とネームスペース宣言を開始要素に追加します。「属性とネームスペース宣言の開始要素への追加」を参照してください。

7. 出力ストリームをクローズします。「出力ストリームのクローズ」を参照してください。

StAXを使用したXML生成の例

次の例では、StAXのXMLStreamWriterインタフェースを使用してXMLドキュメントを生成する単純なプログラムを示します。

このサンプル・プログラムではまず、カレント・ディレクトリにあるoutFile.xmlファイルに出力が書き込まれるように指定して、XMLStreamWriterのインスタンスを作成します。次に、様々なwriteXXX()メソッドを使用して、次のようなXMLファイルをビルドします。

<?xml version='1.0' encoding='utf-8'?>

<!--this is a comment-->
<person xmlns:one="http://namespaceOne" gender="f">
<one:name hair="pigtails" freckles="yes">Pippi Longstocking</one:name>
</person>

XMLStreamWriterインタフェースは、XMLドキュメントが整形式かどうかをチェックしません。各開始要素と終了要素が対応しているかどうかなどを確認するのは、プログラマの役目です。この例では、writeCharacters("\n")メソッドを使用して、テキスト・ファイルへの書込み時にXMLを読みやすくするために新しい行を出力に追加する方法についても示します。

太字のコードは、以降の節で説明します。

package examples.basic;

import java.io.FileOutputStream;
import java.util.Iterator;
import javax.xml.stream.*;
import javax.xml.namespace.QName;

/**
* This is a simple example that illustrates how to use the
* the XMLStreamWriter class to generate XML.
*
* The generated XML file looks like this:
*
*   <?xml version='1.0' encoding='utf-8'?>
*
*   <!--this is a comment-->
*   <person xmlns:one="http://namespaceOne" gender="f">
*       <one:name hair="pigtails" freckles="yes">Pippi Longstocking</one:name>
*   </person>
*
*
* @author Copyright (c) 2003 by BEA Systems. All Rights Reserved.
*/

public class Generate {

public static void main(String args[]) throws Exception {

//
// Get an output factory
//
XMLOutputFactory xmlof = XMLOutputFactory.newInstance();
System.out.println("FACTORY: " + xmlof);

//
// Instantiate a writer
//
XMLStreamWriter xmlw = xmlof.createXMLStreamWriter(new FileOutputStream ("outFile.xml"));
System.out.println("READER:  " + xmlw + "\n");

//
// Generate the XML
//

// Write the default XML declaration
xmlw.writeStartDocument();
xmlw.writeCharacters("\n");
xmlw.writeCharacters("\n");

// Write a comment
xmlw.writeComment("this is a comment");
xmlw.writeCharacters("\n");

// Write the root element "person" with a single attribute "gender"
xmlw.writeStartElement("person");
xmlw.writeNamespace("one", "http://namespaceOne");
xmlw.writeAttribute("gender","f");
xmlw.writeCharacters("\n");

// Write the "name" element with some content and two attributes
xmlw.writeCharacters("    ");
xmlw.writeStartElement("one", "name", "http://namespaceOne");
xmlw.writeAttribute("hair","pigtails");
xmlw.writeAttribute("freckles","yes");
xmlw.writeCharacters("Pippi Longstocking");

// End the "name" element
xmlw.writeEndElement();
xmlw.writeCharacters("\n");

// End the "person" element
xmlw.writeEndElement();

// End the XML document
xmlw.writeEndDocument();

// Close the XMLStreamWriter to free up resources
xmlw.close();

}

}

XMLStreamWriterオブジェクトの取得

次のコードの抜粋で示すように、XMLOutputFactory.createXMLStreamWriter()メソッドを使用し、XMLドキュメントに基づいてXMLStreamWriterオブジェクトをインスタンス化します。

XMLStreamWriter xmlw = xmlof.createXMLStreamWriter(new FileOutputStream ("outFile.xml"));

この例では、xmlofがXMLOutputFactoryインスタンスに当たります。

createXMLStreamWriter()メソッドの様々なシグネチャにより、以下のXMLドキュメント・フォーマットをパラメータとして扱うことができます。

- java.io.OutputStream (例で示します)

- java.io.Writer

- javax.xml.transform.Result (JAXP API http://docs.oracle.com/javase/6/docs/technotes/guides/xml/index.htmlで指定)

出力ストリームへのXML宣言の追加

次のコードの抜粋で示すように、XMLStreamWriter.writeStartDocument()メソッドを使用し、XMLドキュメントの1行目としてXML宣言を追加します。

xmlw.writeStartDocument();

引数を指定しない場合、このメソッドは次のデフォルトXML宣言を記述します。

<?xml version='1.0' encoding='utf-8'?>

別のエンコーディングまたはXMLバージョンを指定する場合は、引数を次のように指定したwriteStartDocument()メソッドを使用します。

- writeStartDocument(java.lang.String version)

- writeStartDocument(java.lang.String encoding, java.lang.String version)

writeStartDocument()メソッドでエンコーディングを設定しても、基底の出力の実際のエンコーディングは設定されません。このエンコーディング設定用の引数は、XML宣言のencoding属性に対してどの値が書き込まれるかを指定するものです。出力のエンコーディングを実際に設定するには、対応するXMLOutputFactory.createXMLStreamWriter()メソッドでXMLStreamWriterのインスタンスを作成する際にencodingパラメータを指定する必要があります。

出力ストリームへの標準XMLイベントの追加

XMLStreamWriter.writeXXX() XXXメソッドを使用すると、開始要素、終了要素、コメント、CDATA、エンティティ参照などの標準的なXMLイベントを出力ストリームに追加できます。writeStartElement(), writeEndElement(), writeComment(), writeCData()などの特定のイベントを指します。テキスト・データまたは名前をStringとして渡すことにより、大部分の要素を作成できます。

XMLStreamWriterインタフェースでは、データの検証や、ドキュメントが整形式かどうかのチェックは行われません。各開始要素と終了要素が対応しているかどうかなどの確認は、プログラマの役目です。また、開始要素と終了要素のイベントが正しくネストされているかどうかを確認することも、プログラマに任されています。テキスト・ファイルへの書込み時に出力XMLを読みやすくするには、writeCharacters("\n")メソッドを使用して、適切な場所に新しい行を追加します。

たとえば、次のような小さなXMLを作成するとします。

<!-- This is a comment -->
<name>Jane Doe</name>

出力ストリームにこの要素を追加するJavaコードは次のようになります。

xmlw.writeComment("This is a comment");
xmlw.writeCharacters("\n");

xmlw.writeStartElement("name");
xmlw.writeCharacters("Jane Doe");
xmlw.writeEndElement();
xmlw.writeCharacters("\n");

属性とネームスペース宣言の開始要素への追加

開始要素イベントの直後にwriteAttribute()メソッドを使用して、属性を要素に追加できます。バインド対象のURIとともに属性の接頭辞を指定することも、属性をまったく指定しないことも可能です。

たとえば、次のような小さなXMLを作成するとします。

<person gender="f">

このXMLを作成するJavaコードは次のとおりです。

xmlw.writeStartElement("person");
xmlw.writeAttribute("gender","f");
xmlw.writeCharacters("\n");

writeNamespace()メソッドを使用すると、出力ストリームにネームスペースを記述できます。現在のイベントで開始要素などのネームスペースの記述を有効にするのはプログラマの役目です。現在のイベントでネームスペースの記述が無効になっている場合は、javax.xml.stream.XMLStreamExceptionが送出されます。イベントの接頭辞やそのバインド対象となるURIを指定するには、それに応じた形式のwriteXXX()メソッドを使用します。

たとえば、次のXML出力では、<person>要素のネームスペース宣言、および<one>子要素用に指定したone接頭辞を示します。

<person xmlns:one="http://namespaceOne" gender="f">
<one:name hair="pigtails" freckles="yes">Pippi Longstocking</one:name>
</person>

このXMLを作成するJavaコードは次のとおりです。

// Write the root element "person" with a single attribute "gender"
xmlw.writeStartElement("person");
xmlw.writeNamespace("one", "http://namespaceOne");
xmlw.writeAttribute("gender","f");
xmlw.writeCharacters("\n");

// Write the "name" element with some content and two attributes
xmlw.writeCharacters("    ");
xmlw.writeStartElement("one", "name", "http://namespaceOne");
xmlw.writeAttribute("hair","pigtails");
xmlw.writeAttribute("freckles","yes");
xmlw.writeCharacters("Pippi Longstocking");

// End the "name" element
xmlw.writeEndElement();
xmlw.writeCharacters("\n");

// End the "person" element
xmlw.writeEndElement();

出力ストリームのクローズ

プログラミング慣行として、作業終了時にXMLStreamWriterを明示的にクローズしてリソースを解放します。ライターをクローズするには、XMLStreamWriter.close()メソッドを使用します。以下に例を示します。

// Close the XMLStreamWriter to free up resources
xmlw.close();

XMLInputFactoryインタフェース用に定義されたプロパティ

表4-2では、XMLInputFactoryを使用してXMLStreamReaderオブジェクトまたはXMLEventReaderオブジェクトを生成する際に設定可能な標準プロパティを示します。

表4-2のプロパティにはjavax.xml.stream.isValidatingのように、いずれも先頭にjavax.xml.streamが付きます。

表4-2 Standard XMLInputFactoryの標準プロパティ

プロパティ

説明

戻り値の型

デフォルト値

isValidating

実装固有のDTD検証を有効にするか無効にするかを指定します。

Boolean

False

isNamespaceAware

ネームスペース処理を有効にするか無効にするかを指定します。XML 1.0がサポートされている場合に使用。

Boolean

True

isCoalescing

隣接する文字データをまとめるかどうかを指定します。

Boolean

False

isReplacingEntityReferences

内部エンティティ参照を置換テキストに置き換え、文字として報告するかどうかを指定します。

Boolean

True

isSupportingExternalEntities

解析対象の外部エンティティを解決するかどうかを指定します。

Boolean

False

supportDTD

使用するプロセッサがDTDをサポートするかどうかを指定します。

Boolean

True

reporter

使用するjavax.xml.stream.XMLReporterの実装を指定します。

XMLReporter

Null

resolver

使用するjavax.xml.stream.XMLResolverの実装を指定します。

XMLResolver

Null

allocator

使用するjavax.xml.stream.util.XMLEventAllocatorの実装を指定します。

util.XMLEventAllocator

Null

XMLOutputFactoryインタフェース用に定義されたプロパティ

表4-3では、XMLOutputFactoryを使用してXMLStreamWriterオブジェクトまたはXMLEventWriterオブジェクトを生成する際に設定可能な標準プロパティを示します。

表4-3のプロパティにはjavax.xml.stream.isValidatingのように、いずれも先頭にjavax.xml.streamが付きます。

表4-3 XMLOutputFactoryの標準プロパティ

プロパティ

説明

戻り値の型

デフォルト値

isRepairingNamespaces

ライターがデフォルト・ネームスペース接頭辞宣言を使用するかどうかを指定します。

XMLの生成時にStAXプロセッサがネームスペースと接頭辞を修正する方法には、いくつかの厳密なルールがあります。詳細は、StAX仕様(http://www.jcp.org/en/jsr/detail?id=173)を参照してください。

Boolean

False

5 高度なXML APIの使い方

この章では、2つの高度なXML API、Java API for XML Registries (JAXR) APIおよびWebLogic XPath APIの使用方法について説明します。

この章の内容は以下のとおりです。

- Java API for XML Registries (JAXR) APIの使い方

- WebLogic XPath APIの使い方

Java API for XML Registries (JAXR) APIの使い方

http://www.oracle.com/technetwork/java/jaxr-138137.htmlのJava API for XML Registries (JAXR) APIは、様々なレジストリ、特にWebサービス・アプリケーションで使用されるXMLレジストリにアクセスするための共通の標準Java APIを提供しています。

抽象レベルでは、レジストリは、パートナシップを組んでいる二者の共同作業を助けるニュートラルな第三者です。レジストリは、通常はWebベースのリソースの形式で、共有リソースとして二者が利用できるものです。これにより両者がWebサービスをパブリッシュ、検索、および使用できるようになるので、レジストリは、どのWebサービス・アーキテクチャでも中核となる要素です。

レジストリには、以下の機能があります。

- 電子的なイエロー・ページ
レジストリは、Webサービス・プロバイダが自社の製品を宣伝し、Webサービス・コンシューマがその製品を検索できる独立したオンライン情報交換サービスを提供します。

レジストリは、業界、地域、販売している製品など、任意かつ柔軟な方法でこれらのWebサービスを分類できます。

- 比較的静的なデータのデータベース
レジストリは、データベースと同様にデータとメタデータを格納します。格納するデータの種類には、次のものがあります。

- 特定のビジネス・プロトコルをXMLフォーマットで記述した協調的ビジネス・プロセスの説明。

- 協調的ビジネス・プロセスに参加している二者。

- 協調的ビジネス・プロセスの間に交換されるXMLドキュメントを記述するXMLスキーマ。
実質的な側面を言えば、レジストリを使用すると、アプリケーションは、比較的静的なデータを信頼性の高い方法で格納し、そのデータを他のアプリケーションと簡単に共有できます。

- また、価格変更や、値引き、販促などの動的なコンテンツを二者間でやり取りする際にレジストリを利用することも可能。

WebLogic Serverでは、JAXR仕様が完全に実装されています。JAXR APIを使用すると、レジストリにアクセスするJAXRクライアントを作成したり、自分でレジストリを作成したりできます。

JAXR APIの使用の詳細は、Java WebサービスのWebページ(http://www.oracle.com/technetwork/java/jaxr-138137.html)を参照してください。

WebLogic XPath APIの使い方

WebLogic XPath APIには、DOM、XMLInputStream、またはXMLOutputStreamとして表現されるドキュメントに対してXPathのマッチングを実行するために必要となる、すべてのクラスが入っています。このAPIは、指定したパターンに適合するXMLドキュメント内のXML要素のサブセットを識別する場合に使用します。

WebLogic XPath APIのAPIリファレンスの追加情報は、Oracle WebLogic Server Java APIリファレンスのweblogic.xml.xpathに関する項およびhttp://www.oracle.com/technetwork/java/jaxr-138137.htmlのJavadocを参照してください。

DOMXPathクラスの使い方

この節では、DOMとして表現されるXMLドキュメントに対してXPathのマッチングを実行するために、WebLogic XPath APIのDOMXPathクラスを使用する方法について説明します。最初に例を示し、次にその例で使われている主な手順について説明します。

DOMXPathクラスの使用例

この節の最後に示すサンプルJavaプログラムでは、次のXMLドキュメントをマッチングに使用しています。

<?xml version='1.0' encoding='us-ascii'?>

<!-- "Purchaseorder". -->

<purchaseorder
department="Sales"
date="01-11-2001"
raisedby="Pikachu"
>
<item
ID="101">
<title>Laptop</title>
<quantity>5</quantity>
<make>Dell</make>
</item>
<item
ID="102">
<title>Desktop</title>
<quantity>15</quantity>
<make>Dell</make>
</item>
<item
ID="103">
<title>Office Software</title>
<quantity>10</quantity>
<make>Microsoft</make>
</item>
</purchaseorder>

Javaコード例は次のとおりです。

package examples.xml.xpath;

import java.io.IOException;
import java.util.Iterator;
import java.util.Set;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
import weblogic.xml.xpath.DOMXPath;
import weblogic.xml.xpath.XPathException;
/**
* This class provides a simple example of how to use the DOMXPath
* API.
*
* @author Copyright (c) 2002 by BEA Systems, Inc. All Rights Reserved.
*/

public abstract class DOMXPathExample {

public static void main(String[] ignored)

throws XPathException, ParserConfigurationException,

SAXException, IOException

{

// create a dom representation of the document

String file = "purchaseorder.xml";

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

factory.setNamespaceAware(true); // doesn't matter for this example

DocumentBuilder builder = factory.newDocumentBuilder();

Document doc = builder.parse(file);

// create some instances of DOMXPath to evaluate against the

// document.

DOMXPath totalItems = // count number of items

new DOMXPath("count(purchaseorder/item)");

DOMXPath atLeast10 =  // titles of items with quantity >= 10

new DOMXPath("purchaseorder/item[quantity >= 10]/title");

// evaluate them against the document

double count = totalItems.evaluateAsNumber(doc);

Set nodeset = atLeast10.evaluateAsNodeset(doc);

// output results

System.out.println(file+" contains "+count+" total items.");

System.out.println("The following items have quantity >= 10:");

if (nodeset != null) {

Iterator i = nodeset.iterator();

while(i.hasNext()) {

Node node = (Node)i.next();

System.out.println("  "+node.getNodeName()+

": "+node.getFirstChild().getNodeValue());

}

}

// note that at this point we are free to continue using evaluate

// atLeast10 and totalItems against other documents

}

}

DOMXPathクラスを使用する場合の主な手順

次の手順では、DOMXPathクラスを使用して、DOMで表現されるXMLドキュメントに対してXPathのマッチングを実行するための主な手順について説明します。

1. 次のサンプル・コードように、XMLドキュメントからorg.w3c.dom.Documentオブジェクトを作成します。

String file = "purchaseorder.xml";
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(file);

2. DOMに対して評価するXPath式を表すDOMXPathオブジェクトを作成します。
次の例では、発注書内の項目数をカウントするXPath式を示します。

DOMXPath totalItems =
new DOMXPath("count(purchaseorder/item)");

次の例では、数量が10以上の項目を持つタイトルを返すXPath式を示します。

DOMXPath atLeast10 =
new DOMXPath("purchaseorder/item[quantity >= 10]/title");

3. DOMXPath.evaluateAsXXX()メソッドの1つを使用して、XPath式を評価します。XXXは、Boolean、Nodeset、Number、Stringといった戻り値のデータ型を表します。
次の例では、evaluateAsNumber()メソッドを使用してtotalItems XPath式を評価する方法を示します。

double count = totalItems.evaluateAsNumber(doc);
System.out.println(file+" contains "+count+" total items.");

次の例では、evaluateAsNodeset()メソッドを使用して、標準的な方法で反復処理できるorg.w3c.dom.NodesのSetを返す方法を示します。

Set nodeset = atLeast10.evaluateAsNodeset(doc);

System.out.println("The following items have quantity >= 10:");
if (nodeset != null) {
Iterator i = nodeset.iterator();
while(i.hasNext()) {
Node node = (Node)i.next();
System.out.println("  "+node.getNodeName()+
": "+node.getFirstChild().getNodeValue());
}
}

WebLogic XPath APIのAPIリファレンスの追加情報は、Oracle WebLogic Server Java APIリファレンスのweblogic.xml.xpathに関する項を参照してください。

StreamXPathクラスの使い方

次の例では、WebLogic XPath APIのStreamXPathクラスを使用して、XMLInputStreamに対してXPathマッチングを実行する方法を示します。最初に例を示し、次にその例で使われている主な手順について説明します。例ではXMLInputStreamに対してマッチングを実行する方法のみを示しますが、同様のコードを使用すればXMLOutputStreamに対してマッチングを実行できます。

StreamXPathクラスの使用例

この節の最後に示すサンプルJavaプログラムでは、次のXMLドキュメントをマッチングに使用しています。

<?xml version='1.0' encoding='us-ascii'?>

<!-- "Stock Quotes". -->

<stock_quotes>
<stock_quote symbol='BEAS'>
<when>
<date>01/27/2001</date>
<time>3:40PM</time>
</when>
<price type="ask"     value="65.1875"/>
<price type="open"    value="64.00"/>
<price type="dayhigh" value="66.6875"/>
<price type="daylow"  value="64.75"/>
<change>+2.1875</change>
<volume>7050200</volume>
</stock_quote>
<stock_quote symbol='MSFT'>
<when>
<date>01/27/2001</date>
<time>3:40PM</time>
</when>
<price type="ask" value="55.6875"/>
<price type="open"    value="50.25"/>
<price type="dayhigh" value="56"/>
<price type="daylow"  value="52.9375"/>
<change>+5.25</change>
<volume>64282200</volume>
</stock_quote>
</stock_quotes>

サンプルのJavaコードは次のとおりです。

package examples.xml.xpath;

import java.io.File;
import weblogic.xml.stream.Attribute;
import weblogic.xml.stream.StartElement;
import weblogic.xml.stream.XMLEvent;
import weblogic.xml.stream.XMLInputStream;
import weblogic.xml.stream.XMLInputStreamFactory;
import weblogic.xml.stream.XMLStreamException;
import weblogic.xml.xpath.StreamXPath;
import weblogic.xml.xpath.XPathException;
import weblogic.xml.xpath.XPathStreamFactory;
import weblogic.xml.xpath.XPathStreamObserver;

/**
* This class provides a simple example of how to use the StreamXPath
* API.
*
* @author Copyright (c) 2002 by BEA Systems, Inc. All Rights Reserved.
*/

public abstract class StreamXPathExample {
public static void main(String[] ignored)
throws XPathException, XMLStreamException
{
// Create instances of StreamXPath for two xpaths we want to match
// against this tream.

StreamXPath symbols =
new StreamXPath("stock_quotes/stock_quote");
StreamXPath openingPrices =
new StreamXPath("stock_quotes/stock_quote/price[@type='open']");

// Create an XPathStreamFactory.

XPathStreamFactory factory = new XPathStreamFactory();

// Create and install two XPathStreamObservers.  In this case, we
// just use to anonymous classes to print a message when a
// callback is received.  Note that a given observer can observe
// more than one xpath, and a given xpath can be observed by
// mutliple observers.

factory.install(symbols, new XPathStreamObserver () {
public void observe(XMLEvent event) {
System.out.println("Matched a quote: "+event);
}

public void observeAttribute(StartElement e, Attribute a) {} //ignore

public void observeNamespace(StartElement e, Attribute a) {} //ignore

});

// Note that we get matches for both a start and an end elements,
// even in the case of <price/> which is an empty element - this
// is the behavior of the underlying streaming parser.
factory.install(openingPrices, new XPathStreamObserver () {
public void observe(XMLEvent event) {
System.out.println("Matched an opening price: "+event);
}
public void observeAttribute(StartElement e, Attribute a) {} //ignore
public void observeNamespace(StartElement e, Attribute a) {} //ignore
});
// get an XMLInputStream on the document
String file = "stocks.xml";
XMLInputStream sourceStream = XMLInputStreamFactory.newInstance().
newInputStream(new File(file));
// use the factory to create an XMLInputStream that will do xpath
// matching against the source stream
XMLInputStream matchingStream = factory.createStream(sourceStream);
// now iterate through the stream
System.out.println("Matching against xml stream from "+file);
while(matchingStream.hasNext()) {
// we don't do anything with the events in our example - the
// XPathStreamObserver instances that we installed in the
// factory will get callbacks for appropriate events
XMLEvent event = matchingStream.next();
}
}
}

StreamXPathクラスを使用する場合の主な手順

次の手順では、StreamXPathクラスを使用して、XMLInputStreamとして表現されるXMLドキュメントに対してXPathのマッチングを実行するための主な手順を説明します。

1. XMLInputStreamに対して評価するXPath式を表すStreamXPathオブジェクトを作成します。

StreamXPath symbols =
new StreamXPath("stock_quotes/stock_quote");

次の例では、開始値を使用して株価を検索するXPath式を示します。

StreamXPath openingPrices = new   StreamXPath("stock_quotes/stock_quote/price[@type='open']");

2. XPathStreamFactoryを作成します。このファクトリ・クラスを使用して、XMLInputStreamに対して評価するStreamXPathオブジェクトのセットを指定し、XPathに一致するものが見つかった場合にコールバックを登録するためのオブザーバ(XPathStreamObserverインタフェースを使用する)を作成します。次の例では、XPathStreamFactoryの作成方法を示します。

XPathStreamFactory factory = new XPathStreamFactory();

3. XPathStreamFactory.install()メソッドを使用し、1番目のStreamXPathパラメータでXPath式を、2番目のXPathStreamObserverパラメータでオブザーバを指定して、オブザーバを作成およびインストールします。次の例は、無名クラスを使用してXPathStreamObserverインタフェースを実装する方法を示します。observe()メソッドの実装は、コールバックを受け取ったときにメッセージの出力だけを行います。例では、observeAttribute()メソッドとobserveNamespace()メソッドは何もしません。

factory.install(symbols, new XPathStreamObserver () {
public void observe(XMLEvent event) {
System.out.println("Matched a quote: "+event);
}
public void observeAttribute(StartElement e, Attribute a) {}
public void observeNamespace(StartElement e, Attribute a) {}
}
);

4. XMLドキュメントからXMLInputStreamを作成します。

String file = "stocks.xml";

XMLInputStream sourceStream =
XMLInputStreamFactory.newInstance().newInputStream(new File(file));

5. XPathStreamFactoryのcreateStream()メソッドを使用して、元のXMLInputStreamに対してXPathのマッチングを実行する新しいXMLInputStreamを作成します。

XMLInputStream matchingStream =
factory.createStream(sourceStream);

6. 新しいXMLInputStreamを反復処理します。反復処理中にXPathに一致するものが見つかった場合、登録済みのオブザーバに通知されます。

while(matchingStream.hasNext()) {
XMLEvent event = matchingStream.next();
}

WebLogic XPath APIのAPIリファレンスの追加情報は、Oracle WebLogic Server Java APIリファレンスのweblogic.xml.xpathに関する項を参照してください。

6 XMLプログラミングのベスト・プラクティス

この章では、XMLデータを処理するJavaアプリケーションを作成する場合に使用するプログラミング上の最良の方法について説明します。

この章の内容は以下のとおりです。

- DOM、SAX、StAX APIを使用する場合

- XML検証のパフォーマンスの改善

- XMLスキーマまたはDTDを使用する場合

- パフォーマンスを最大にする外部エンティティ解決の構成

- SAX InputSourceの使用

- 変換のパフォーマンスの向上

DOM、SAX、StAX APIを使用する場合

DOM、SAX、StAX APIによりXMLドキュメントを解析できます。この節では、各APIの長所および短所について説明します。

DOM APIは、小さなドキュメント、すなわち要素数が1000個以下のドキュメントに向いています。DOMはXMLデータのツリーを構成するので、要素の追加または削除によりXMLドキュメントの構造を編集するには理想的です。

DOM APIでは、処理を開始する前に、まずXMLドキュメント全体を解析し、DOMツリーに変換します。このコストは、ドキュメント全体にアクセスする必要のあることがわかっている場合には有意義です。XMLドキュメントの一部にしかアクセスする必要のない場合には、アプリケーションのパフォーマンスが低下するだけで、何のメリットもないことがあります。そのような場合は、SAXまたはStAX APIが適しています。

SAX APIは最も軽いAPIです。ユニークな要素名の入った浅いドキュメント(要素のネストがあまりないドキュメント)の解析に理想的です。SAXでは、コールバック構造が使用されます。つまり、APIでXMLドキュメントの読取りを行っている間に、プログラマ側でイベントの解析を処理します。これは、比較的効率的で迅速な解析方法です。

ただし、SAXのコールバックの性質上、XMLデータの構造を変更する場合に必ずしも最良のAPIが使用されるとは限りません。また、コールバックを処理するアプリケーションのプログラミングは、わかりやすい直感的なものではありません。

StAX APIはSAXをベースにしているので、SAXを使用する理由はすべてStAX APIにも当てはまります。さらに、プログラマはイベント発生時にイベントに対応するのではなく、イベントを請求するので、StAX APIの方がSAXを使用するより直感的です。StAX APIは、パラメータとしてXMLドキュメント全体を渡す場合にも最適です。入力ストリームを渡す方が、SAXイベントを渡すよりも簡単だからです。最後に、StAX APIは、元々XMLデータをJavaオブジェクトにバインドするために設計されたものです。

XML検証のパフォーマンスの改善

パーサー検証問題によりXMLアプリケーションのパフォーマンスが低下した状況で、XMLドキュメントの検証を行う必要がある場合、DocumentBuilderFactoryまたはSaxParserFactoryのsetValidating()メソッドを使用するのではなく、データを受信または解析するときに検証する独自のカスタム・コードを記述することで、アプリケーションのパフォーマンスを改善できる場合があります。

SAXまたはDOMでXMLドキュメント解析中の検証をオンにした場合、パーサーはユーザーが実際に必要とするより多くの検証を行うことがあり、その結果、アプリケーションの全体的パフォーマンスが低下します。XMLドキュメントが有効であるかをチェックする場合は、ドキュメントの解析中に適切なポイントを選択し、それらのポイントに独自のJavaコードを追加することを検討してください。

たとえば、WebLogic XML Streaming APIによりXML発注書を処理するアプリケーションを書くと仮定します。ドキュメントの最初の要素は<purchase_order>でなければならないことがわかっているので、ストリームから最初の要素を取り出してその名前をチェックすることで、そのドキュメントが有効に見えるかどうかを迅速に検証できます。もちろん、このチェックはXMLドキュメント全体が有効であることを保証するものではありませんが、ストリームから要素を取り出しながら、既知の要素についてさらにチェックを続けることができます。このようなクイック・チェックは、標準のsetValidating()メソッドを使用する場合に比べてはるかに高速です。

XMLスキーマまたはDTDを使用する場合

XMLドキュメントの構造の記述方法には、DTDおよびXMLスキーマの2種類があります。

最近は、スキーマによりXMLドキュメントを記述する傾向にあります。スキーマは、XML要素を記述するために利用できるデータ・タイプのセットがDTDよりはるかに豊富で、DTDより表現力があり、XMLドキュメントで何が有効であるかを詳しく記述できます。また、SOAPメッセージではスキーマのみを使用でき、DTDは使用できません。SOAPはWebサービスで使用される主要なメッセージング・プロトコルであり、Webサービスに対する入力パラメータまたは出力パラメータとして使用されるXMLドキュメントを記述するには、スキーマを使用することを検討してください。

DTDにもいくつかの利点があります。DTDは、急速に変化しつつあるスキーマより広い範囲でサポートされています。DTDはスキーマほどの表現力がないので、作成や管理が簡単です。

Oracleでは、XMLドキュメントの記述にはスキーマを使用することをお薦めします。

パフォーマンスを最大にする外部エンティティ解決の構成

外部エンティティは、いつもネットワークから取得するのではなく、可能な限りローカルに格納しておくことを強くお薦めします。エンティティをネットワーク接続を介して探すよりも、WebLogic Serverと同じマシン上で探す方がはるかに高速であるため、ローカルに格納することでアプリケーションのパフォーマンスが向上します。

WebLogic Serverの外部エンティティ解決の構成の詳細は、「外部エンティティの構成タスク」を参照してください。

SAX InputSourceの使用

SAX APIによりXMLドキュメントを解析する場合、まずXMLドキュメントからInputSourceオブジェクトを作成し、そのInputSourceオブジェクトをparse()メソッドに渡します。InputSourceオブジェクトは、XMLデータに基づいて、java.io.InputStreamオブジェクトまたはjava.io.Readerオブジェクトから作成できます。

可能な限り、java.io.InputStreamオブジェクトからInputSourceを作成することをお薦めします。InputStreamオブジェクトが渡されると、SAXパーサーは、XMLデータの文字エンコーディングを自動検出し、正しい文字エンコーディングを使用して、InputStreamReaderオブジェクトを自動的にインスタンス化します。つまり、ユーザーにかわってパーサーが文字エンコーディングのすべての作業を行うので、文字エンコーディングをユーザー自身が指定する場合より、実行時のエラーが大幅に減少します。

変換のパフォーマンスの向上

XSLTは、XMLドキュメントを、別のXMLドキュメント、HTML、WMLなど、異なるフォーマットに変換するための言語です。XSLTを使用するには、入力XMLドキュメントの各要素を出力ドキュメントでどのように変換するかを定義するスタイルシートを作成します。

XSLTは強力な言語ですが、複雑な変換のためのスタイルシートの作成は非常に煩雑になることがあります。また、実際の変換には大量のリソースが必要であり、アプリケーションのパフォーマンスが低下することがあります。

したがって、変換が複雑な場合は、XSLTスタイルシートを使用するのではなく、アプリケーションで独自の変換コードを書くことを検討してください。また、DOM APIの使用も検討してください。まず、XMLドキュメントを解析し、結果のDOMツリーを必要に応じて操作し、それを最終フォーマットに変換するためのカスタムJavaコードを使用して、新しいドキュメントを書き出します。

7 XMLプログラミング手法

この章では、XMLデータを処理するWebLogic ServerのJava EEアプリケーションを開発するための特定のXMLプログラミング手法について説明します。

この章の内容は以下のとおりです。

- JavaクライアントとWebLogic Serverとの間でのXMLデータの転送

- JMSアプリケーションでのXMLドキュメントの処理

- HTTPインタフェースを持たない外部エンティティへのアクセス

JavaクライアントとWebLogic Serverとの間でのXMLデータの転送

一般的なJava EEアプリケーションでは、クライアント・アプリケーションは、XMLデータを処理するサーブレットまたはJSPにXMLデータを送信します。次に、サーブレットまたはJSPは、そのデータをJMS宛先やEJBなどの別のJava EEコンポーネントに送信するか、または処理したXMLデータを別のXMLドキュメントの形でクライアントに返します。

JavaクライアントからWebLogic ServerにホストされたサーブレットまたはJSPにXMLデータを送信し、クライアントにデータが返されるようにするには、java.net.URLConnectionクラスを使用します。このクラスは、アプリケーションとURL (この場合は、サーブレットまたはJSPを呼び出すURL)の間の通信リンクを表します。URLConnectionクラスのインスタンスは、HTTP POSTメソッドを使用してXMLドキュメントを送信します。

WebLogic XMLサンプルから抜粋した次のJavaクライアント・プログラムは、プログラムとJSPの間でXMLデータを転送する方法を示しています。

import java.net.*;
import java.io.*;
import java.util.*;
public class Client {
public static void main(String[] args) throws Exception {
if (args.length < 2) {
System.out.println("Usage:  java examples.xml.Client URL Filename");
}
else {
try {
URL url = new URL(args[0]);
String document = args[1];
FileReader fr = new FileReader(document);
char[] buffer = new char[1024*10];
int bytes_read = 0;
if ((bytes_read = fr.read(buffer)) != -1)
{
URLConnection urlc = url.openConnection();
urlc.setRequestProperty("Content-Type","text/xml");
urlc.setDoOutput(true);
urlc.setDoInput(true);
PrintWriter pw = new PrintWriter(urlc.getOutputStream());
// send xml to jsp
pw.write(buffer, 0, bytes_read);
pw.close();
BufferedReader in = new BufferedReader(new InputStreamReader(urlc.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
in.close();
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}
}

この例では、引数リストからのURLを使用してJSPへのURL接続をオープンし、その接続から出力ストリームを取得し、引数リストに指定されたXMLドキュメントを出力ストリームに出力して、XMLデータをJSPに送信する方法を示しています。次に、URLConnectionクラスのgetInputStream()メソッドを使用して、JSAPがクライアント・アプリケーションに返すXMLデータを読み取る方法の例を示します。

サンプルJSPから抜粋した次のコード・セグメントでは、JSPがクライアント・アプリケーションからXMLデータを受信し、XMLドキュメントを解析して、XMLデータを返す方法を示しています。

BufferedReader br = new BufferedReader(request.getReader());
DocumentBuilderFactory fact = DocumentBuilderFactory.newInstance();
DocumentBuilder db = fact.newDocumentBuilder();
Document doc = db.parse(new InputSource(br));
...
PrintWriter responseWriter = response.getWriter();
responseWriter.println("<?xml version='1.0'?>");

...

WebLogicサーブレットとJSPのプログラミングの詳細は、『Oracle WebLogic Server Webアプリケーション、サーブレット、JSPの開発』を参照してください。

JMSアプリケーションでのXMLドキュメントの処理

WebLogic Serverは、JMSアプリケーションでXMLドキュメントを処理するために一部のJava Message Service (JMS)クラスに対して次の拡張を提供しています。

- weblogic.jms.extensions.WLSession。JMSクラスjavax.jms.Sessionを拡張します。

- weblogic.jms.extensions.WLQueueSession。JMSクラスjavax.jms.QueueSessionを拡張します。

- weblogic.jms.extensions.WLTopicSession。JMSクラスjavax.jms.TopicSessionを拡張します。

- weblogic.jms.extensions.XMLMessage。JMSクラスjavax.jms.TextMessageを拡張します。

より一般的なTextMessageクラスではなく、XMLMessageクラスを使用して、JMSアプリケーションでXMLドキュメントを送受信する場合、XML固有のメッセージ・セレクタを使用して不要なメッセージをフィルタ処理できます。特に、JMS_BEA_SELECTメソッドを使用すると、XMLドキュメントのXMLフラグメントを検索するためのXPath問合せを指定できます。問合せの結果に基づいて、メッセージ・コンシューマがメッセージを受信しないよう決定することもあります。これにより、ネットワーク・トラフィックを軽減し、JMSアプリケーションのパフォーマンスを向上させることができます。

XMLMessageクラスを使用してJMSアプリケーションにXMLメッセージを含めるには、WLQueueSessionオブジェクトまたはWLTopicSessionオブジェクトのいずれかを作成する必要があります。どちらのオブジェクトを作成するかは、JMS Connectionを作成した後に、汎用オブジェクトQueueSessionまたはTopicSessionではなく、JMSキューまたはトピックを使用するかどうかによります。次に、WLSessionインタフェースのcreateXMLMessage()メソッドを使用してXMLMessageオブジェクトを作成します。

JMSアプリケーションでのXMLMessageオブジェクトの使用の詳細は、『Oracle WebLogic Server JMSアプリケーションの開発』を参照してください。

HTTPインタフェースを持たない外部エンティティへのアクセス

WebLogic Serverは、外部リポジトリにある外部エンティティに、エンティティを返すURLなどのHTTPインタフェースがある限り、その外部エンティティを自動的に取得およびキャッシュできます。XMLレジストリで外部エンティティを構成する際の詳細は、「外部エンティティの構成タスク」を参照してください。

HTTPインタフェースを持たないリポジトリに格納されている外部エンティティにアクセスする場合は、インタフェースを作成する必要があります。たとえば、システムID、パブリックID、DTDのテキストの列を持つデータベース表にXMLドキュメント用のDTDを格納しているとします。WebLogic XMLアプリケーションから外部エンティティとしてDTDにアクセスする場合、JDBCを使用してデータベースのDTDにアクセスするサーブレットを作成できます。

URLでサーブレットを呼び出すので、ここで外部エンティティに対するHTTPインタフェースを持っていることになります。XMLレジストリでエンティティ・レジストリ・エントリを作成する場合、外部エンティティの場所としてサーブレットを呼び出すURLを指定します。WebLogic Serverは、この外部エンティティへの参照を含むXMLドキュメントを解析しているときにサーブレットを呼び出し、サーブレットがデータベースの問合せに内部で使用するパブリックIDおよびシステムIDをサーブレットに渡します。

8 XMLアプリケーション・スコーピング

この章では、アプリケーション・スコーピングについて、また特定のアプリケーションのためにパーサー、トランスフォーマ、外部エンティティ、外部エンティティ・キャッシュを構成する方法について説明します。

この章の内容は以下のとおりです。

- アプリケーション・スコーピングの概要

- weblogic-application.xmlファイル

- エンタープライズ・アプリケーション用のパーサーまたはトランスフォーマの構成

- エンタープライズ・アプリケーション用の外部エンティティの構成

- エンタープライズ・アプリケーション用の外部エンティティ・キャッシュの構成

アプリケーション・スコーピングの概要

アプリケーション・スコープとは、WebLogic Serverの構成全体に対してではなく、特定のエンタープライズ・アプリケーションに対してリソースを構成することです。XMLの場合、このようなリソースとしては、パーサー、トランスフォーマ、外部エンティティ、および外部エンティティのキャッシュ構成があります。アプリケーション・スコープの最大の利点は、特定のアプリケーションに対するリソースがそのアプリケーション専用になることです。アプリケーション・スコーピングによって、アプリケーションごとに異なるパーサーを構成したり、EARファイルや展開されたエンタープライズ・ディレクトリ内のアプリケーション用にDTDを保管したりすることができます。

アプリケーション・スコーピングを使用するもう1つのメリットは、リソースをEARファイルと関連付けることにより、WebLogic Serverの別のインスタンスで、そのサーバーのリソースを構成せずにこのEARファイルを実行できることです。

特定のアプリケーション用のXMLリソースを構成するには、EARファイルまたは展開されたエンタープライズ・アプリケーション・ディレクトリのMETA-INFディレクトリにあるweblogic-application.xmlデプロイメント記述子ファイルに情報を追加します。

注意:

WebLogic Serverインスタンス用のパーサー、トランスフォーマ、および外部エンティティ・リソースを構成するには、第9章「WebLogic Server XMLの管理」で説明するように、管理コンソールを使用します。

weblogic-application.xmlファイル

weblogic-application.xmlファイルは、エンタープライズ・アプリケーション用のWebLogic Server固有のデプロイメント記述子です。このファイルには、エンタープライズ・アプリケーションにより使用されるXML、JDBC、EJBなどのリソースに関する構成情報が入れられます。標準Java EEデプロイメント記述子は、application.xmlと呼ばれます。

次のサンプル・ファイルweblogic-application.xmlは、あるエンタープライズ・アプリケーション用のXMLリソースを構成する方法を示しています。各種要素の本文は太字で示します。

<weblogic-application>
...
<xml>
<parser-factory>
<saxparser-factory>
com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl
</saxparser-factory>
<document-builder-factory>
com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl
</document-builder-factory>
<transformer-factory>
com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl
</transformer-factory>
</parser-factory>
<entity-mapping>
<entity-mapping-name>My Mapping</entity-mapping-name>
<public-id>-//BEA Systems, Inc.//DTD for cars//EN</public-id>
<system-id>http://www.bea.com/dtds/car.dtd</system-id>
<entity-uri>dtds/car.dtd</entity-uri>
</entity-mapping>
</xml>
</weblogic-application>

XMLリソースを構成するためのメイン要素は、<xml>です。図8-1は、<xml>要素の下位要素を説明します。この図の後の節は各要素を説明します。

図8-1 weblogic-application.xmlの<xml>要素の下位要素

「図8-1 weblogic-application.xmlの<xml>要素の下位要素」の説明

xml

パーサー、トランスフォーマ、外部エンティティ、外部エンティティ・キャッシュなど、エンタープライズ・アプリケーション用XMLリソースを構成するためのメイン要素。

parser-factory

エンタープライズ・アプリケーション用の特定のパーサーまたはトランスフォーマを指定するための親要素。

saxparser-factory

このアプリケーションでSAXスタイル解析のために使用されるファクトリ・クラスを指定する要素。この要素が指定されていない場合、WebLogic Serverインスタンスに対して指定されたデフォルトSAXパーサー・ファクトリが使用されます。

document-builder-factory

このアプリケーションでDOMスタイル解析のために使用されるファクトリ・クラスを指定する要素。この要素が指定されていない場合、WebLogic Serverインスタンスに対して指定されたデフォルトDOMパーサー・ファクトリが使用されます。

transformer-factory

このアプリケーションでjavax.xml.transformパッケージによりドキュメントを変換する場合に使用されるファクトリ・クラスを指定する要素。この要素が指定されていない場合、WebLogic Serverインスタンスに対して指定されたデフォルトXSLTトランスフォーマ・ファクトリが使用されます。

entity-mapping

DTDやスキーマなど、XMLファイル内のエンティティ宣言をエンティティのローカル・コピーにマッピングするための親要素。

entity-mapping-name

エンティティ・マッピング宣言の名前を指定する要素。

public-id

次のようなエンティティのパブリックIDを指定する要素。

-//BEA Systems, Inc.//DTD for cars//EN.

system-id

次のようなエンティティのシステムIDを指定する要素。

http://www.bea.com/dtds/car.dtd

entity-uri

エンティティのURIを指定する要素。このパスは、EARアーカイブまたは展開ディレクトリのメイン・ディレクトリを基準とする相対パスです。

たとえば、dtds/car.dtdは、メインEARアーカイブ(META-INFディレクトリと同じレベル)にdtdsというディレクトリがあり、そこにcar.dtdというファイルがあることを示します。

when-to-cache

外部エンティティをキャッシュする時期を指定する要素。有効な値は以下のとおりです:

- cache-on-reference - WebLogic Serverは、最初にエンティティがXMLドキュメントで参照されたときに、URLで参照される外部エンティティをキャッシュします。

- cache-at-initialization - WebLogic Serverは、サーバー起動時にエンティティをキャッシュします。

- cache-never - WebLogic Serverは、外部エンティティをキャッシュしません。

デフォルト値はcache-on-referenceです。

cache-timeout-interval

キャッシュされた外部エンティティが古くなる(期限切れになる)までの秒数を指定する要素。キャッシュされたコピーがこの期間を超えた場合、WebLogic Serverは、EARアーカイブまたは展開ディレクトリのメイン・ディレクトリを基準に指定された相対URLまたはパス名から外部エンティティを再取得します。

このフィールドのデフォルト値は、120秒です。

エンタープライズ・アプリケーション用のパーサーまたはトランスフォーマの構成

XMLアプリケーションが、WebLogic Serverに構成されているデフォルト・パーサーまたはトランスフォーマとは異なるパーサーまたはトランスフォーマを使用するように指定できます。それには、XMLアプリケーションの入っているEARファイルまたは展開ディレクトリのweblogic-application.xmlを更新します。

エンタープライズ・アプリケーション用にデフォルト以外のパーサーまたはトランスフォーマを構成するには、以下の手順を実行します。

1. <xml>要素の<parser-factory>下位要素を使用し、エンタープライズ・アプリケーションのために、SAXおよびDOMスタイル解析用とXSLT変換用のファクトリ・クラスを構成します。次に例を示します。

<parser-factory>
<saxparser-factory>
com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl
</saxparser-factory>
<document-builder-factory>
com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl
</document-builder-factory>
<transformer-factory>
com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl
</transformer-factory>
</parser-factory>

このweblogic-application.xmlファイルに対応するアプリケーションでは、SAXスタイル解析にはcom.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImplファクトリ・クラス、DOMスタイル解析にはcom.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImplファクトリ・クラス、XSLT変換にはcom.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImplクラスが使用されます。

2. パーサー・クラスまたはトランスフォーマ・クラスをEARアーカイブに対してローカルにするには、そのクラスの入っているJARファイルをEARファイルの任意の場所に置き、META-INF/MANIFEST.MFファイル内のClass-Path変数を更新します。
たとえば、ディレクトリlib/xmlにあるmyparser.jarというJARファイルにパーサー・クラスまたはトランスフォーマ・クラスを置く場合、以下に示すようにMANIFEST.MFファイルを更新します。

Manifest-Version: 1.0
Created-By: 1.3.1_01 (Sun Microsystems Inc.)
Class-Path: lib/xml/myparser.jar

3. パーサー・クラスまたはトランスフォーマ・クラスをEARアーカイブ以外の場所に格納する場合は、クラスの入っているJARファイルの完全パス名を含むようにWebLogic Server CLASSPATH変数を必ず更新してください。

エンタープライズ・アプリケーション用の外部エンティティの構成

DTDなどの外部エンティティは、Webから取得するだけでなく、そのローカル・コピーをEARアーカイブまたは展開ディレクトリに格納しておくこともできます。

エンタープライズ・アプリケーション用の外部エンティティを構成するには:

1. EARアーカイブのメイン・ディレクトリの下にディレクトリlib/xml/registryを作成します。

2. DTDのような外部エンティティをそのディレクトリにコピーします。

3. weblogic-application.xmlファイルを更新し、<xml>要素の<entity-mapping>下位要素を使用して、アプリケーションで処理されるXMLファイルのエンティティ宣言にエンティティの名前をマップします。以下に例を示します。

<entity-mapping>
<entity-mapping-name>My Mapping</entity-mapping-name>
<public-id>-//BEA Systems, Inc.//DTD for cars//EN</public-id>
<system-id>http://www.bea.com/dtds/car.dtd</system-id>
<entity-uri>dtds/car.dtd</entity-uri>
</entity-mapping>

この例では、car.dtdというDTDのローカル・コピーがEARアーカイブまたは展開ディレクトリのメイン・ディレクトリの下にあるlib/xml/registry/dtdsディレクトリに格納されます。このエンティティのパブリックIDは-//BEA Systems, Inc.//DTD for cars//ENで、システムIDはhttp://www.bea.com/dtds/car.dtdです。アプリケーションがXMLファイルの解析中に、これらのIDのいずれかを使用しているエンティティ宣言を検出すると、その宣言はcar.dtdファイルに置き換えられます。

注意:

エンティティのローカル・コピーをマップする各エンティティ宣言について、<entity-mapping>要素を指定してください。

エンタープライズ・アプリケーション用の外部エンティティ・キャッシュの構成

サーバー起動時、またはエンティティの最初の参照時のいずれかに、EARアーカイブのメイン・ディレクトリを基準にした相対URLまたはパス名で参照される外部エンティティをWebLogic Serverがキャッシュするように指定できます。

外部エンティティをキャッシュすると、リモート・アクセス時間が節約されるだけでなく、ネットワークまたは管理サーバーのダウンによりXMLドキュメントの解析中に管理サーバーにアクセスできなくなった場合には、ローカル・バックアップを利用できます。

キャッシュされたエンティティについて、WebLogic ServerがURLまたはEARのディレクトリからエンティティを再取得して再キャッシュする間隔(有効期限)を構成できます。

エンタープライズ・アプリケーション用の外部エンティティ・キャッシュを構成するには、<entity-mapping>要素の<when-to-cache>下位要素と<cache-timeout-interval>下位要素を使用します。以下に例を示します。

<entity-mapping>
<entity-mapping-name>My Mapping</entity-mapping-name>
<public-id>-//BEA Systems, Inc.//DTD for cars//EN</public-id>
<system-id>http://www.bea.com/dtds/car.dtd</system-id>
<entity-uri>dtds/car.dtd</entity-uri>
<when-to-cache>cache-at-initialization</when-to-cache>
<cache-timeout-interval>300</cache-timeout-interval>
</entity-mapping>

この例では、car.dtdがEARアーカイブまたは展開ディレクトリのメイン・ディレクトリの下にあるlib/xml/registry/dtdsディレクトリに格納されます。WebLogic Serverの最初の起動時にDTDのコピーがメモリーにキャッシュされ、以後は、キャッシュされたコピーが300秒以上格納されている場合にリフレッシュされます。

9 WebLogic Server XMLの管理

この章では、管理コンソールからアクセスできるXMLレジストリを使用する、WebLogic ServerでのXMLの管理について説明します。

この章の内容は以下のとおりです。

- WebLogic Server XMLの管理の概要

- XMLパーサーおよびトランスフォーマの構成タスク

- 外部エンティティの構成タスク

WebLogic Server XMLの管理の概要

管理コンソールからXMLレジストリにアクセスし、XMLレジストリでWebLogic ServerをXMLアプリケーション用に構成します。

ブラウザで管理コンソールを起動するには、次のURLを入力します。

http://host:port/console

ここで

- hostは、WebLogic管理サーバーが動作しているコンピュータの名前です。

- portは、WebLogic管理サーバーが接続リクエストのリスニングを行っているポート番号です。WebLogic管理サーバーのデフォルトのポート番号は7001です。

XMLの管理タスク

XMLレジストリは、管理コンソールを使用して作成、構成、および使用します。管理コンソールXMLレジストリの使用には、次のメリットがあります。

- XMLアプリケーションでJAXPを使用している場合、XMLレジストリの構成の変更が実行時に自動的に有効になります。

- XMLレジストリを変更する場合、XMLアプリケーション・コードを変更する必要はありません。

- エンティティの解決がローカルで実行されます。XMLレジストリでは、エンティティのローカル・コピーを定義できます。または、WebLogic ServerがWebからエンティティを指定した期間キャッシュし、Web上のエンティティではなく、そのキャッシュしたコピーを使用するように指定することもできます。

XMLレジストリを使用すると、以下の指定が可能になります。

- デフォルト・パーサーのかわりとなるサーバー全体のXMLパーサー。

- ドキュメント・タイプ単位のXMLパーサー。

- デフォルトのトランスフォーマのかわりとなる、サーバー全体の代替トランスフォーマ。

- エンティティのローカル・コピーで解決される外部エンティティ。外部エンティティを指定すると、管理サーバーでは、エンティティのローカル・コピーがファイル・システムに保存され、解析時にサーバーのパーサーに自動的に配布されます。この機能を使用すれば、SAX EntityResolversの作成と設定が不要になります。

- Webからの取得後にWebLogic Serverによってキャッシュされる外部エンティティ。WebLogic Serverが再取得するまでこれらの外部エンティティがキャッシュされる期間、およびWebLogicが最初にエンティティを取得するタイミング(アプリケーションの実行時か、WebLogic Serverの起動時か)を指定します。

これらの機能は、サーバー側だけで使用できます。

XMLレジストリの仕組み

XMLレジストリを必要な数だけ作成できますが、WebLogic Serverの特定のインスタンスに関連付けることができるXMLレジストリの数は1つだけです。

WebLogic ServerのインスタンスにXMLレジストリが関連付けられていない場合、ドキュメントの解析や変換にはデフォルトのパーサーおよびトランスフォーマが使用されます。デフォルトのパーサーおよびトランスフォーマは、JDKバージョン5.0に付属しています。

XMLレジストリをWebLogic Serverのインスタンスに関連付けると、すべてのXML構成オプションが、そのサーバーを使用しているXMLアプリケーションで利用可能になります。

XMLレジストリに対しては、以下のタイプのエントリを作成できます。

- パーサーおよびトランスフォーマの構成。

- 外部エンティティ解決の構成。

注意:

XMLレジストリでは、大文字と小文字が区別されます。たとえば、ルート要素が<CAR>のXMLドキュメント・タイプのパーサーを構成している場合、「ルート要素タグ」フィールドには、carやCarではなくCARと入力する必要があります。

XMLレジストリ内のパーサーの選択

JAXPでXMLアプリケーションを解析または変換する場合は、常にXMLレジストリに自動的にアクセスします。WebLogic Serverは、以下のようなルックアップ順序に従って、ロードするパーサーのクラスを決定します。

1. 特定のドキュメント・タイプ用に定義したパーサーを使用します。

2. WebLogic Serverインスタンスに関連付けられているXMLレジストリで定義されたサーバー全体の代替パーサーを使用します。

3. デフォルト・パーサー(JDK 5.0に付属のパーサー)を使用します。

特定のドキュメント・タイプに対応するトランスフォーマを定義することはできないので最初の手順は除きますが、それ以外ではこのプロセスはトランスフォーマにも当てはまります。

さらに、WebLogic Serverの起動時に、SAXエンティティ・リゾルバは、レジストリで宣言されたエンティティを解決するように自動的に設定されます。したがって、使用するパーサーを制御したり、外部エンティティのローカル・コピーの場所を設定したりするために、XMLアプリケーション・コードを変更する必要はありません。使用するパーサー、および外部エンティティの位置は、XMLレジストリで制御します。

注意:

JAXPではなくパーサーによって提供されたAPIを使用する場合、XMLレジストリはXMLドキュメントの処理に影響を与えません。このため、XMLアプリケーションではなるべくJAXPを使用してください。

XMLパーサーおよびトランスフォーマの構成タスク

デフォルトでは、WebLogic Serverは、デフォルト・パーサーとトランスフォーマでXMLドキュメントを解析および変換するように構成されています。デフォルトのパーサーおよびトランスフォーマは、JDK 5.0に付属しています。デフォルトを使用する限りは、XMLアプリケーションについて構成タスクを実行する必要はありません。デフォルト以外のパーサーまたはトランスフォーマを使用する場合は、以下の節で説明するようにXMLレジストリでパーサーおよびトランスフォーマを構成する必要があります。

デフォルト以外のパーサーまたはトランスフォーマの構成

次の手順ではまず、SAXおよびDOMパーサーおよびトランスフォーマを定義するXMLレジストリの作成方法を説明します。次に、サーバーで新しいパーサーとトランスフォーマを使用するために、新しいXMLレジストリをWebLogic Serverのインスタンスに関連付ける(プラグインする)方法を説明します。

注意:

デフォルトのWebLogic Serverパーサーおよびトランスフォーマと互換性があるパーサーおよびトランスフォーマのみをプラグインできます。デフォルトのパーサーおよびトランスフォーマは、JDK 5.0に付属しています。

1. WebLogic管理サーバーを起動し、管理コンソールをブラウザで起動します。管理コンソールの呼出し方法については、「WebLogic Server XMLの管理の概要」を参照してください。

2. Oracle WebLogic Server管理コンソール・オンライン・ヘルプのXMLレジストリの作成に関する項で説明されている手順に従います。

特定のドキュメント・タイプに対応したパーサーの構成

特定のドキュメント・タイプに対応したパーサーを構成する場合、ドキュメントのシステムID、パブリックID、ルート要素を使用して、ドキュメント・タイプを識別できます。

注意:

WebLogic Serverでは、ドキュメントの種類を識別しようとするとき、XMLドキュメントの最初の1000バイトのみを検索します。この最初の1000バイトの中にDOCTYPE識別子が見つからなければ、ドキュメントの検索は終了し、WebLogic Serverインスタンス用に構成されたパーサーを使用してドキュメントの解析が行われます。

特定のドキュメント・タイプに対応したパーサーを構成するには、以下の手順を実行します。

1. WebLogic管理サーバーを起動し、管理コンソールをブラウザで起動します。
管理コンソールの呼出し方法については、「WebLogic Server XMLの管理の概要」を参照してください。

2. Oracle WebLogic Server管理コンソール・オンライン・ヘルプのドキュメントの種類に対するパーサーの関連付けに関する項で説明されている手順に従います。

外部エンティティの構成タスク

XMLレジストリを使用すると、外部エンティティ解決を構成し、外部エンティティ・キャッシュを構成およびモニターできます。

外部エンティティ解決の構成

WebLogic Serverでは、以下のいずれかの方法で外部エンティティの解決を構成できます。

- 物理的にエンティティ・ファイルを、WebLogic管理サーバーからアクセス可能なディレクトリにコピーし、外部エンティティがXMLドキュメントで参照されている場合は常に管理サーバーがそのローカル・コピーを使用するように指定します。

- サーバー起動時、または外部エンティティの初めての参照時のいずれかに、管理サーバーを基準にした相対URLまたはパス名で参照される外部エンティティを管理対象サーバーがキャッシュするように指定します。
外部エンティティを管理対象サーバーにキャッシュすると、アクセス時間を節約できるだけでなく、ネットワークまたは管理サーバーのダウンによりXMLドキュメントの解析中に管理サーバーにアクセスできなくなった場合には、ローカル・バックアップを利用できます。

キャッシュされたエンティティに対して、WebLogic ServerがURLまたは管理サーバーからエンティティを再取得して再キャッシュするまでの間隔(有効期限)を構成できます。

外部エンティティの解決を構成するには、以下の手順を実行します。

1. WebLogic管理サーバーを起動し、管理コンソールをブラウザで起動します。
管理コンソールの呼出し方法については、「WebLogic Server XMLの管理の概要」を参照してください。

2. Oracle WebLogic Server管理コンソール・オンライン・ヘルプの外部エンティティ解決の構成に関する項で説明されている手順に従います。

外部エンティティ・キャッシュの構成

外部エンティティ・キャッシュの以下のプロパティを構成できます。

- キャッシュ・メモリーのサイズ(単位: KB)。このプロパティのデフォルト値は500KBです。

- 永続ディスク・キャッシュのサイズ(MB)。このプロパティのデフォルト値は5MBです。

- 外部エンティティがWebLogic Serverによってキャッシュされた後、キャッシュ内で有効期限切れになるまでの秒数。これは、サーバー全体のデフォルト値です。エンティティを構成する場合に、特定の外部エンティティに対応するようにこの値をオーバーライドできます。このプロパティのデフォルト値は、120秒(2分)です。

外部エンティティ・キャッシュを構成するには、次の手順に従います。

1. WebLogic管理サーバーを起動し、管理コンソールをブラウザで起動します。
管理コンソールの呼出し方法については、「WebLogic Server XMLの管理の概要」を参照してください。

2. Oracle WebLogic Server管理コンソール・オンライン・ヘルプのXMLエンティティ・キャッシュの作成に関する項で説明されている手順に従います。

A XMLリファレンス

以下の節では、WebLogic ServerでサポートされるXML仕様、アプリケーション・プログラミング・インタフェース(API)、およびツールに関する補足情報へのリンクを示します。

- XML API

- サンプル・コード

- WebLogic Serverの関連ドキュメント

- チュートリアルとオンライン・コース

- その他のXML仕様と情報

XML API

- http://www.saxproject.org/にあるSAX 2.0 API

- http://www.w3.org/TR/DOM-Level-2/にあるDOM (Document Object Model) Level 2仕様

- http://docs.oracle.com/javase/6/docs/technotes/guides/xml/index.htmlにあるJAXP API 1.2仕様

サンプル・コード

XMLサンプル・コードとサポートするドキュメントは、必要に応じて、WebLogic ServerのEXAMPLES_HOME\wl_server\examples\src\examplesディレクトリ(EXAMPLES_HOMEはWebLogic Serverサンプル・コードが構成されているディレクトリ)に組み込まれます。WebLogic Serverのサンプル・コードの詳細は、『Oracle WebLogic Serverの理解』のサンプル・アプリケーションおよびサンプル・コードに関する項を参照してください。

WebLogic Serverの関連ドキュメント

- 『Oracle WebLogic Server JAX-WS Webサービスの開発』

- 『WebLogic Server Enterprise JavaBeansバージョン2.1の開発』

- 『Oracle WebLogic Server JMSアプリケーションの開発』

- Oracle WebLogic Server Webアプリケーション、サーブレット、JSPの開発

チュートリアルとオンライン・コース

- XMLの技術概説: http://www.xml.com/pub/a/98/10/guide0.htmlで入手可能

- XMLオーサリング・チュートリアル: http://www.xml.com/pub/r/32で入手可能

- Java 2プラットフォームおよびXMLテクノロジを使用するためのチュートリアル: http://developerlife.com/で入手可能

- XML、Java、そしてWebの未来: http://www.xml.com/pub/a/w3j/s3.bosak.htmlで入手可能

- XMLバイブルの第17章「XSL変換」: http://metalab.unc.edu/xml/books/bible/updates/14.htmlで入手可能

- 『XSL Tutorial』(Nic Miloslav著): http://zvon.org/xxl/XSLTutorial/Output/index.htmlで入手可能

- XMLスキーマ・パート0「入門」: http://www.w3.org/TR/2000/CR-xmlschema-0-20001024/で入力可能

その他のXML仕様と情報

- XML 1.0仕様は、(http://www.w3.org/TR/REC-xml/)にあります。

- XMLSchema Part 1: Structuresは、(http://www.w3.org/TR/xmlschema-1/)にあります。

- XML Schema Part 2: Datatypesは、(http://www.w3.org/TR/xmlschema-2)にあります。

- XMLネームスペースは、「http://www.w3.org/TR/REC-xml-names/」にあります。

- Extensible Stylesheet Language (XSL) 1.0仕様は、(http://www.w3.org/TR/xsl/)にあります。

- JSR-000031 XML Data Binding仕様は(http://jcp.org/en/jsr/detail?id=031)にあります。

- XML Path Language (XPath) Version 1.0仕様は、(http://www.w3.org/TR/xpath)にあります。

- XML Linking Language (XLink)仕様は、(http://www.w3.org/TR/xlink)にあります。

- XML Pointer Language (XPointer)仕様は、「http://www.w3.org/TR/WD-xptr」にあります。

- W3C (World Wide Web Consortium)のホーム・ページは、(http://www.w3c.org)にあります。

- XML.comのホーム・ページは、(http://www.xml.com)にあります。

- XML FAQページは、(http://www.ucc.ie/xml/)にあります。

- XML.org, The XML Industry Portalは、(http://www.xml.org/)にあります。

B WebLogic XML Streaming APIの使用(非推奨)

注意:

WebLogic XML Streaming APIはWebLogic Serverリリース9.0の時点で非推奨となっています。かわりに、Java Community Processによる標準仕様Streaming API for XML (StAX)を使用してください。詳細は、第4章「Streaming API for XML (StAX)の使い方」を参照してください。

以下の節では、WebLogic XML Streaming APIによりXMLドキュメントの解析と生成を行う方法について説明します。

- WebLogic XML Streaming APIの概要

- WebLogic XML Streaming APIのJavadoc

- XMLドキュメントの解析:一般的な手順

- 新しいXMLドキュメントの生成:一般的な手順

WebLogic XML Streaming APIの概要

WebLogic XML Streaming APIは、XMLドキュメントを解析および生成するための簡単でわかりやすい手段を提供します。SAX APIと似ていますが、XMLドキュメントに対する手続き的なストリーム・ベースの処理が可能であり、SAXイベント・ハンドラを作成する必要はありません。SAXイベント・ハンドラで複雑なXMLドキュメントを扱うと、ハンドラ自体が複雑になる場合があります。つまり、Streaming APIを利用すれば、SAX APIよりきめ細かく解析を制御できます。

SAXを使用してXMLドキュメントを解析する場合、プログラムでは、イベント発生時に解析をリスニングするイベント・リスナーを作成し、特定のイベントを請求するのではなくイベントに対して対応する必要があります。一方、Streaming APIを使用する場合は、XMLドキュメントを手順の流れに沿って処理すること、特定のタイプのイベント(要素の開始など)を請求すること、要素の属性を繰返し処理すること、ドキュメントの先頭をスキップすること、任意の時点で処理を停止すること、特定の要素の下位要素を取得すること、指定どおりに要素をフィルタ処理することができます。イベントに対応するのではなく、イベントを請求するので、Streaming APIを使用する方法は、プル解析と呼ばれることもあります。

Streaming APIにより、オペレーティング・システム上のXMLファイル、DOMツリー、SAXイベントのセットなど、多くのタイプのXMLドキュメントを解析できます。これらのXMLドキュメントをイベントのストリーム、すなわちXMLInputStreamに変換し、このストリームを順に処理して、要素の開始、ドキュメントの終了などのイベントを必要に応じてスタックから取得します。

WebLogic Streaming APIは、デフォルト・パーサーとしてWebLogic FastParserを使用します。

Streaming APIを使用してXMLドキュメントを解析する完全なサンプルは、EXAMPLES_HOME\wl_server\examples\src\examplesディレクトリ(EXAMPLES_HOMEはWebLogic Serverサンプル・コードが構成されているディレクトリ)を参照してください。WebLogic Serverのサンプル・コードの詳細は、『Oracle WebLogic Serverの理解』のサンプル・アプリケーションおよびサンプル・コードに関する項を参照してください。

表B-1で、WebLogic Streaming APIの主なインタフェースとクラスについて説明します。

表B-1 XML Streaming APIのインタフェースとクラス

インタフェースまたはクラス

説明

XMLInputStreamFactory

XMLドキュメント解析用のXMLInputStreamオブジェクトを作成するために使用されるファクトリ。

XMLInputStream

イベントの入力ストリームを入れるために使用されるインタフェース。

BufferedXMLInputStream

XMLInputStreamインタフェースでストリームのマーキングとリセットを行えるようにするための拡張。

XMLOutputStreamFactory

XMLドキュメント生成用のXMLOutputStreamオブジェクトを作成するために使用されるファクトリ。

XMLOutputStream

イベントを書き込むために使用されるインタフェース。

ElementFactory

このAPIで使用されるインタフェースのインスタンスを作成するためのユーティリティ。

XMLEvent

要素の開始、要素の終了など、XMLドキュメントでのすべてのタイプのイベントのための基本インタフェース。

StartElement

XMLEventサブ・インタフェースの最重要部。XMLドキュメントの開始要素に関する情報を取得するために使用されます。

AttributeIterator

要素の属性のセットを繰返し処理するために使用されるオブジェクト。

Attribute

要素の特定の属性を記述するオブジェクト。

WebLogic XML Streaming APIのJavadoc

以下のJavadocには、この章で説明したWebLogic XML Streaming API機能に加え、詳しく説明されていない機能に関するリファレンスが掲載されています。

- weblogic.xml.stream

- weblogic.xml.stream.util

XMLドキュメントの解析:一般的な手順

以下の手順は、WebLogic XML Streaming APIによりXMLドキュメントの解析と操作を行う一般的手順について説明したものです。

最初の2つの手順は必須です。その後の手順は、XMLファイルをどのように処理するかに応じて実行します。

1. weblogic.xml.stream.*クラスをインポートします。

2. XMLファイル、DOMツリー、またはSAXイベントのセットからイベントのXMLストリームを取得します。XMLストリームをフィルタ処理することにより、特定のタイプのイベント、特定の要素の名前などのみを取得することもできます。「XML入力ストリームの取得」を参照してください。

3. ストリームを繰返し処理し、汎用XMLEventタイプを返します。「ストリームの繰返し処理」を参照してください。

4. 汎用XMLEventタイプのそれぞれについて、イベント・タイプを判別します。イベント・タイプには、XMLドキュメント、要素の終了、エンティティ参照などがあります。「特定のXMLEventタイプの判別」を参照してください。

5. 要素の属性を取得します。「要素の属性の取得」を参照してください。

6. イベント全体のスキップ、特定のイベントのスキップなどにより、ストリームを位置決めします。「ストリームの位置決め」を参照してください。

7. 要素の子を取得します。「サブストリームの取得」を参照してください。

8. ストリームをクローズします。「入力ストリームのクローズ」を参照してください。

XMLドキュメント解析の例

以下の節では、XML Streaming APIによりXMLドキュメントを解析する例を示します。

このプログラムは、XMLファイルを表す1つのパラメータを取り、そのファイルをXML入力ストリームに変換します。次に、ストリームを繰返し処理し、XML要素の開始、XMLドキュメントの終了など、各イベントのタイプを判別します。開始要素、終了要素、および要素の本文を形成する文字データの3つのタイプのイベントについては、情報が出力されます。コメントやXMLドキュメントの開始など、その他のタイプのイベントについては、何も行われません。

注意:

太字のコードについては、例の後の節で詳しく説明します。

package examples.xml.stream;
import weblogic.xml.stream.Attribute;
import weblogic.xml.stream.AttributeIterator;
import weblogic.xml.stream.ChangePrefixMapping;
import weblogic.xml.stream.CharacterData;
import weblogic.xml.stream.Comment;
import weblogic.xml.stream.XMLEvent;
import weblogic.xml.stream.EndDocument;
import weblogic.xml.stream.EndElement;
import weblogic.xml.stream.EntityReference;
import weblogic.xml.stream.ProcessingInstruction;
import weblogic.xml.stream.Space;
import weblogic.xml.stream.StartDocument;
import weblogic.xml.stream.StartPrefixMapping;
import weblogic.xml.stream.StartElement;
import weblogic.xml.stream.EndPrefixMapping;
import weblogic.xml.stream.XMLInputStream;
import weblogic.xml.stream.XMLInputStreamFactory;
import weblogic.xml.stream.XMLName;
import weblogic.xml.stream.XMLStreamException;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class ComplexParse {
/**
* Helper method to get a handle on a stream.
* Takes in a name and returns a stream.  This
* method usese the InputStreamFactory to create an
* instance of an XMLInputStream
* @param name The file to parse
* @return XMLInputStream the stream to parse
*/
public XMLInputStream getStream(String name)
throws XMLStreamException, FileNotFoundException
{
XMLInputStreamFactory factory = XMLInputStreamFactory.newInstance();
XMLInputStream stream = factory.newInputStream(new FileInputStream(name));
return stream;
}
/**
*  Determines the type of event, such as the start
*  of an element, end of a document, and so on.  If the
*  event is of type START_ELEMENT, END_ELEMENT, or
*  CHARACTER_DATA, the method prints out appropriate info;
*  otherwise, it does nothing.
*  @param event The XML event that has been parsed
*/
public void parse(XMLEvent event)
throws XMLStreamException
{
switch(event.getType()) {
case XMLEvent.START_ELEMENT:
StartElement startElement = (StartElement) event;
System.out.print("<" + startElement.getName().getQualifiedName() );
AttributeIterator attributes = startElement.getAttributesAndNamespaces();
while(attributes.hasNext()){
Attribute attribute = attributes.next();
System.out.print(" " + attribute.getName().getQualifiedName() +
"='" + attribute.getValue() + "'");
}
System.out.print(">");
break;
case XMLEvent.END_ELEMENT:
System.out.print("</" + event.getName().getQualifiedName() +">");
break;
case XMLEvent.SPACE:
case XMLEvent.CHARACTER_DATA:
CharacterData characterData = (CharacterData) event;
System.out.print(characterData.getContent());
break;
case XMLEvent.COMMENT:
// Print comment
break;
case XMLEvent.PROCESSING_INSTRUCTION:
// Print ProcessingInstruction
break;
case XMLEvent.START_DOCUMENT:
// Print StartDocument
break;
case XMLEvent.END_DOCUMENT:
// Print EndDocument
break;
case XMLEvent.START_PREFIX_MAPPING:
// Print StartPrefixMapping
break;
case XMLEvent.END_PREFIX_MAPPING:
// Print EndPrefixMapping
break;
case XMLEvent.CHANGE_PREFIX_MAPPING:
// Print ChangePrefixMapping
break;
case XMLEvent.ENTITY_REFERENCE:
// Print EntityReference
break;
case XMLEvent.NULL_ELEMENT:
throw new XMLStreamException("Attempt to write a null event.");
default:
throw new XMLStreamException("Attempt to write unknown event
["+event.getType()+"]");
}
}
/**
* Helper method to iterate over a stream
* @param name The file to parse
*/
public void parse(XMLInputStream stream)
throws XMLStreamException
{
while(stream.hasNext()) {
XMLEvent event = stream.next();
parse(event);
}
stream.close();
}
/** Main method.   Takes a single argument: an XML file
*  that will be converted into an XML input stream.
*/
public static void main(String args[])
throws Exception
{
ComplexParse complexParse= new ComplexParse();
complexParse.parse(complexParse.getStream(args[0]));
}
}

XML入力ストリームの取得

XML Streaming APIにより、XMLファイルDOMツリー、SAXイベントなど、様々なオブジェクトをイベントのストリームに変換できます。

次の例で、XMLファイルからイベントのストリームを変換する方法を示します。

XMLInputStreamFactory factory = XMLInputStreamFactory.newInstance();
XMLInputStream stream = factory.newInputStream(new FileInputStream(name));

まず、XMLInputStreamFactoryの新しいインスタンスを作成し、次に、このファクトリを使用して、name変数で参照されるXMLファイルから新しいXMLInputStreamを作成します。

次の例では、DOMツリーからストリームを作成する方法を示します。

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setValidating(false);
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new java.io.File(file));
XMLInputStream stream = XMLInputStreamFactory.newInstance().newInputStream(doc);

バッファされたXML入力ストリームの取得

XMLInputStreamオブジェクトの繰返し処理を終了した後は、このストリームに再度アクセスすることはできません。ただし再度ストリームを処理する必要がある場合、たとえば、ストリームを別のアプリケーションに送信したり、別の方法で再度繰返し処理したりする場合は、XMlInputStreamオブジェクトではなく、BufferedXMLInputStreamオブジェクトを使用できます。

バッファされたXML入力ストリームを作成するには、XMLInputStreamFactoryクラスのnewBufferedInputStream()メソッドを使用します。以下に例を示します。

XMLInputStreamFactory factory = XMLInputStreamFactory.newInstance();
BufferedXMLInputStream bufstream =
factory.newBufferedInputStream(factory.newInputStream(new
FileInputStream(name)));

BufferedXMLInputStreamオブジェクトのmark()メソッドとreset()メソッドにより、ストリームの特定のスポットをマークし、ストリームの処理を続け、マークしたスポットに戻るようにストリームをリセットできます。「バッファされたXML入力ストリームのマーキングとリセット」を参照してください。

XMLストリームのフィルタ処理

XMLストリームのフィルタ処理とは、指定したタイプのオブジェクトのみの入ったストリームを作成することです。たとえば、開始要素、終了要素、およびXML要素の本文をマークアップする文字データのみの入ったストリームを作成できます。別の例では、指定した名前を持つ要素のみがストリームに出現するようにXMLストリームをフィルタ処理することもできます。

XMLストリームをフィルタ処理するには、XMLInputStreamFactory.newInputStream()メソッドの2番目のパラメータとしてフィルタ・クラスを指定します。フィルタ・クラスに対するパラメータとしてXMLストリームに入れるイベントを指定します。次の例では、TypeFilterクラスにより、結果のXMLストリームにXMLの開始要素と終了要素、および文字データのみを入れるように指定する方法を示します。

import weblogic.xml.stream.util.TypeFilter;
XMLInputStreamFactory factory = XMLInputStreamFactory.newInstance();
XMLInputStream stream = factory.newInputStream(new FileInputStream(name),
new TypeFilter(XMLEvent.START_ELEMENT |
XMLEvent.END_ELEMENT |
XMLEvent.CHARACTER_DATA));

表B-2で、WebLogic XML Streaming APIに用意されているフィルタについて説明します。これらは、weblogic.xml.stream.utilパッケージの一部です。

表B-2 WebLogic XML Streaming APIによって提供されるフィルタ

フィルタの名前

説明

使用例

TypeFilter

XMLEvent.START_ELEMENT、XMLEvent.END_ELEMENTなど、指定されたイベント・タイプに基づいてXMLストリームをフィルタ処理します。イベント・タイプの詳細なリストについては、「特定のXMLEventタイプの判別」を参照してください。

TypeFilterは、入力として整数ビット・マスクを取ります。例に示すとおり、このビット・マスクを作成するには、値のOR (論理和)を取ります。

new TypeFilter (XMLEvent.START_ELEMENT |
XMLEvent.END_ELEMENT |
XMLEvent.CHARACTER_DATA)

NameFilter

XMLドキュメント内の要素の名前に基づいてXMLストリームをフィルタ処理します。

new NameFilter ("Book")

NameSpaceFilter

指定されたネームスペースURIに基づいてXMLストリームをフィルタ処理します。

new NameSpaceFilter ("http://namespace.org")

NamespaceTypeFilter

指定されたイベント・タイプとネームスペースURIに基づいてXMLストリームをフィルタ処理します。このフィルタは、TypeFilterとNameSpaceFilterの機能を結合したものです。

new NamespaceFilter ("http://namespace.org", XMLEvent.START_ELEMENT)

この例は、すべての開始要素が指定されたネームスペースを持っているストリームを返します。

カスタム・フィルタの作成

APIに入っているフィルタがニーズに合わない場合は、独自のフィルタを作成することもできます。

1. ElementFilterインタフェースを実装し、accept(XMLEvent)というメソッドを持つクラスを作成します。このメソッドは、ストリームに特定のイベントを追加するかどうかをXMLInputStreamFactory.newInputStream()メソッドに通知します。以下に例を示します。

package my.filters;

import weblogic.xml.stream.XMLName;
import weblogic.xml.stream.ElementFilter;
import weblogic.xml.stream.events.NullEvent;

public class SuperDooperFilter implements ElementFilter {

protected String name;

public SuperDooperFilter(String name)
{
this.name = name;
}

public boolean accept(XMLEvent e) {
if (name.equals(e.getName().getLocalName()))
return true;
return false;
}
}

2. XMLアプリケーションで、新しいフィルタ・クラスをインポートしていることを確認します。

import my.filters.SuperDooperFilter

3. newInputStream()メソッドの2番目のパラメータとしてフィルタを指定します。これは、XMLストリームに入れるイベントのタイプを、フィルタ・クラスが必要とするフォーマットでフィルタ・クラスに渡します。

XMLInputStreamFactory factory = XMLInputStreamFactory.newInstance();
XMLInputStream stream = factory.newInputStream(new FileInputStream(name),
new SuperDooperFilter(param));

ストリームの繰返し処理

イベントのストリームが完成したら、次にXMLInputStream.next()メソッドとXMLInputStream.hasNext()メソッドを使用して、イベントのストリームを手順に沿って処理します。以下に例を示します。

while(stream.hasNext()) {
XMLEvent event = stream.next();
System.out.print(event);
}

特定のXMLEventタイプの判別

XMLInputStream.next()メソッドは、XMLEventタイプのオブジェクトを返します。XMLEventには、このイベントが、XMLドキュメントの開始、要素の終了、エンティティ参照などのどれであるかをさらに分類するサブインタフェースがあります。XMLEventインタフェースには、対応するフィールド、すなわち定数、ならびに実際のイベントを識別するために使用できるメソッドのセットも入っています。図B-1では、XMLEventインタフェースとそのサブインタフェースの階層を示します。

図B-1 XMLEventインタフェースとそのサブインタフェースの階層

「図B-1 XMLEventインタフェースとそのサブインタフェースの階層」の説明

表B-3に、XMLストリームの解析時に特定のイベントを識別するために使用できるXMLEventクラスのサブクラスとフィールドをリストします。

表B-3 XMLEventクラスのサブクラスとフィールド

XMLEventサブクラス

サブクラスを識別するために使用されるXMLEventクラスのフィールド

サブクラスを識別するために使用されるメソッド

サブクラス・イベントの説明

ChangePrefixMapping

CHANGE_PREFIX_MAPPING

isChangePrefixMapping

接頭辞マッピングが古いネームスペースから新しいネームスペースに変更されたことを示します。

CharacterData

CHARACTER_DATA

isCharacterData

返されたXMLEventオブジェクトに要素の本文からの文字データが入っていることを示します。

Comment

COMMENT

isComment

返されたXMLEventオブジェクトにXMLコメントが入っていることを示します。

EndDocument

END_DOCUMENT

isEndDocument

XMLドキュメントの終了を示します。

EndElement

END_ELEMENT

isEndElement

XMLドキュメントの要素の終了を示します。

EndPrefixMapping

END_PREFIX_MAPPING

isEndPrefixMapping

接頭辞マッピングがスコープの範囲外になったことを示します。

EntityReference

ENTITY_REFERENCE

isEntityReference

返されたXMLEventオブジェクトにエンティティ参照が入っていることを示します。

ProcessingInstruction

PROCESSING_INSTRUCTION

isProcessingInstruction

返されたXMLEventオブジェクトに処理指示が入っていることを示します。

Space

SPACE

isSpace

返されたXMLEventオブジェクトにホワイトスペースが入っていることを示します。

StartDocument

START_DOCUMENT

isStartDocument

XMLドキュメントの開始を示します。

StartElement

START_ELEMENT

isStartElement

XMLドキュメントの要素の開始を示します。

StartPrefixMapping

START_PREFIX_MAPPING

isStartPrefixMapping

接頭辞マッピングがそのスコープを開始したことを示します。

次の例では、Java case文を使用して、XMLInputStream.next()メソッドにより返されたイベントのタイプを判別する方法を示します。簡単にするため、この例では、見つかったイベントをそのまま出力します。イベントをさらに処理する方法は、その後の節で示します。

switch(event.getType()) {
case XMLEvent.START_ELEMENT:
// Start of an element
System.out.println ("Start Element\n");
break;

case XMLEvent.END_ELEMENT:
// End of an element
System.out.println ("End Element\n");
break;

case XMLEvent.PROCESSING_INSTRUCTION:
// Processing Instruction
System.out.println ("Processing instruction\n");
break;

case XMLEvent.SPACE:
// Whitespace
System.out.println ("White space\n");
break;

case XMLEvent.CHARACTER_DATA:
// Character data
System.out.println ("Character data\n");
break;

case XMLEvent.COMMENT:
// Comment
System.out.println ("Comment\n");
break;

case XMLEvent.START_DOCUMENT:
// Start of the XML document
System.out.println ("Start Document\n");
break;

case XMLEvent.END_DOCUMENT:
// End of the XML Document
System.out.println ("End Document\n");
break;

case XMLEvent.START_PREFIX_MAPPING:
// The start of a prefix mapping scope
System.out.println ("Start prefix mapping\n");
break;

case XMLEvent.END_PREFIX_MAPPING:
// The end of a prefix mapping scope
System.out.println ("End prefix mapping\n");
break;

case XMLEvent.CHANGE_PREFIX_MAPPING:
// Prefix mapping has changed namespaces
System.out.println ("Change prefix mapping\n");
break;

case XMLEvent.ENTITY_REFERENCE:
// An entity reference
System.out.println ("Entity reference\n");
break;
default:

throw new XMLStreamException("Attempt to parse unknown event
[" + event.getType() + "]");
}

要素の属性の取得

XMLドキュメントの要素の属性を取得するには、まず、XMLInputStream.next()メソッドにより返されたXMLEventオブジェクトをStartElementオブジェクトにキャストする必要があります。

要素に属性がいくつあるかが分からないため、まず、属性のリスト全体を入れるAttributeIteratorオブジェクトを作成してから、属性がなくなるまでリストを繰返し処理します。次の例で、「ストリームの繰返し処理」に示したswitch文のSTART_ELEMENT caseの一部としてこれを行う方法を示します。

case XMLEvent.START_ELEMENT:

StartElement startElement = (StartElement) event;
System.out.print("<" + startElement.getName().getQualifiedName() );
AttributeIterator attributes = startElement.getAttributesAndNamespaces();
while(attributes.hasNext()){
Attribute attribute = attributes.next();
System.out.print(" " + attribute.getName().getQualifiedName() +
"='" + attribute.getValue() + "'");
}
System.out.print(">");
break;

この例では、まず、返されたXMLEventをStartElementにキャストすることにより、StartElementオブジェクトを作成します。次に、StartElement.getAttributesAndNamespaces()メソッドを使用してAttributeIteratorオブジェクトを作成し、AttributeIterator.hasNext()メソッドを使用して属性を繰返し処理します。各Attributeについて、Attributes.getName().getQualifiedName()メソッドとAttribute.getValue()メソッドを使用し、属性の名前と値を返します。

getNamespace()メソッドやgetAttributes()メソッドを使用すると、ネームスペースや属性のみを返すこともできます。

ストリームの位置決め

表B-4で、ストリームの特定の位置までスキップするために使用できるXMLInputStreamインタフェースのメソッドについて説明します。

表B-4 入力ストリームの位置決めのために使用されるメソッド

XMLInputStreamのメソッド

説明

skip()

入力ストリームを次のストリーム・イベントに位置決めします。

注意: 次のイベントは、XMLファイル内の実際の要素であるとはかぎりません。コメントやホワイトスペースの場合もあります。

skip(int)

入力ストリームをこのタイプの次のイベントに位置決めします。

イベント・タイプの例としては、XMLEvent.START_ELEMENTやXMLEvent.END_DOCUMENTなどがあります。イベント・タイプの詳細なリストについては、「表B-3」を参照してください。

skip(XMLName)

入力ストリームをこの名前の次のイベントに位置決めします。

skip(XMLName, int)

入力ストリームをこの名前とタイプの次のイベントに位置決めします。

skipElement()

次の要素にスキップします(現在の要素の下位要素にはスキップしません)。

peek()

ストリームから実際には読み込まずに、次のイベントをチェックします。

次の例では、入力ストリームを繰返し処理する基本コードを修正し、XML要素の本文の文字データをスキップする方法を示します。

while(stream.hasNext()) {
XMLEvent peek = stream.peek();
if (peek.getType() == XMLEvent.CHARACTER_DATA ) {
stream.skip();
continue;
}
XMLEvent event = stream.next();
parse(event);
}

この例は、XMLInputStream.peek()メソッドを使用してストリーム上の次のイベントを判別する方法を示しています。イベントのタイプがXMLEvent.CHARACTER_DATAである場合、そのイベントはスキップされ、次のイベントに進みます。

サブストリームの取得

すべての下位要素も含め、次の要素のコピーを取得するには、XMLInputStream.getSubStream()メソッドを使用します。getSubstream()メソッドは、XMLInputStreamオブジェクトを返します。親ストリーム(またはgetSubStream()を呼び出したストリーム)での位置は移動しません。親ストリームでは、getSubStream()で取得した要素をスキップする場合、skipElement()メソッドを使用します。

getSubStream()メソッドは、検出されたSTART_ELEMENTイベントとEND_ELEMENTイベントの数を記録し、その数が等しくなると(すなわち、完全な次の要素が見つかると)停止して、結果のサブストリームをXMLInputStreamオブジェクトとして返します。

たとえば、XML Streaming APIを使用して以下のXMLドキュメントを解析するとします。ただし、<content>タグと</content>タグに囲まれたサブストリームのみを対象にします。

<book>
<title>The History of the World</title>
<author>Juliet Shackell</author>
<publisher>CrazyDays Publishing</publisher>
<content>
<chapter title='Just a Speck of Dust'>
<synopsis>The world as a speck of dust</synopsis>
<para>Once the world was just a speck of dust...</para>
</chapter>
<chapter title='Life Appears'>
<synopsis>Move over dust, here comes life.</synopsis>
<para>Happily, the dust got a companion: life...</para>
</chapter>
</content>
</book>

次のコード(抜粋)は、<content>開始要素タグにスキップし、サブストリームを取得し、独立したComplexParseオブジェクトを使用してそのサブストリームを解析する方法を示しています。

if (stream.skip( ElementFactory.createXMLName("content")))
{
ComplexParse complexParse = new ComplexParse();
complexParse.parse(stream.getSubStream());
}

前のXMLドキュメントでこのメソッドを呼び出すと、以下の出力が得られます。

<content>
<chapter title='Just a Speck of Dust'>
<synopsis>The world as a speck of dust</synopsis>
<para>Once the world was just a speck of dust...</para>
</chapter>
<chapter title='Life Appears'>
<synopsis>Move over dust, here comes life.</synopsis>
<para>Happily, the dust got a companion: life...</para>
</chapter>
</content>

バッファされたXML入力ストリームのマーキングとリセット

BufferedXMLInputStreamオブジェクトを使用する場合、mark()メソッドとreset()メソッドにより、ストリームの特定のスポットをマークし、ストリームの処理を続けた後、マークしたスポットに戻るようにストリームをリセットできます。この2つのメソッドは、最初に繰返し処理をした後で、ストリームをさらに操作したい場合に便利です。

注意:

バッファされたストリームをマーキングせずに読み取った場合、直前に読み取ったものにアクセスすることはできません。つまり、ストリームはバッファされるだけであり、自動的にストリームを再読取りできることを意味するわけではありません。まずストリームをマークしておく必要があります。

次の例で、BufferedXMLInputStreamオブジェクトの一般的な使い方を示します。

XMLInputStreamFactory factory = XMLInputStreamFactory.newInstance();
BufferedXMLInputStream bufstream =
factory.newBufferedInputStream(factory.newInputStream(new
FileInputStream(name)));

// mark the start of the stream
bufstream.mark();

// process it locally
bufferedParse.parse(bufstream);

// reset the stream to the mark
bufstream.reset();

// send stream off to another application
ComplexParse complexParse =  new ComplexParse();
complexParse.parse(bufstream);

入力ストリームのクローズ

プログラミング慣行として、XML入力ストリームでの作業終了時に入力ストリームを明示的にクローズします。入力ストリームをクローズするには、XMLInputStream.close()メソッドを使用します。以下に例を示します。

// close the input stream
input.close();

新しいXMLドキュメントの生成:一般的な手順

次の手順では、WebLogic XML Streaming APIにより新しいXMLドキュメントを生成する一般的手順について説明します。

最初の2つの手順は必須です。その後の手順は、XMLファイルをどのように生成するかに応じて実行します。

1. weblogic.xml.stream.*クラスをインポートします。

2. XMLドキュメントを書き込むためのXML出力ストリームを作成します。「XML出力ストリームの作成」を参照してください。

3. XML出力ストリームにイベントを追加します。「出力ストリームへの要素の追加」を参照してください。

4. XML出力ストリームに属性を追加します。「出力ストリームの要素への属性の追加」を参照してください。

5. 出力ストリームに入力ストリームを追加します。「出力ストリームへの入力ストリームの追加」を参照してください。

6. 出力ストリームを出力します。「出力ストリームの出力」を参照してください。

7. 出力ストリームをクローズします。「出力ストリームのクローズ」を参照してください。

XMLドキュメント生成の例

以下の節では、XML Streaming APIによりXMLドキュメントを生成する例を示します。

このプログラムでは、まず、PrintWriterオブジェクトに基づいて出力ストリームを作成し、次に、その出力ストリームに要素を追加して、プログラムのコメントに説明されているように、単純なXML発注書を作成します。また、別のXMLファイルに基づく入力ストリームを出力ストリームに追加する方法も示します。

注意:

サンプルの後の節に、さらに詳しい説明があります。

package examples.xml.stream;

import weblogic.xml.stream.XMLInputStream;
import weblogic.xml.stream.XMLOutputStream;
import weblogic.xml.stream.XMLInputStreamFactory;
import weblogic.xml.stream.XMLName;
import weblogic.xml.stream.XMLEvent;
import weblogic.xml.stream.StartElement;
import weblogic.xml.stream.EndElement;
import weblogic.xml.stream.Attribute;
import weblogic.xml.stream.ElementFactory;
import weblogic.xml.stream.XMLStreamException;
import weblogic.xml.stream.XMLOutputStreamFactory;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.PrintWriter;

/**
* Program that prints out a very simple purchase order that looks
* like the following:
*
* <purchase_order>
*  <name>Juliet Shackell</name>
*  <item id="1234" quantity="2">Fabulous Chair</item>
*  <!-- this is a comment-->
*  <another_file>
*    This comes from another file called "another_file.xml"
*  </another_file>
* </purchase_order>
*
* In the preceding XML file, the <another_file> element is actually another
* XML file that is passed as an argument to the program, converted into an
* XMLInputStream, then added to the output stream.
*/
public class PrintPurchaseOrder {

/**
* Helper method to get a handle on a stream.
* Takes in a name and returns a stream.  This
* method uses the InputStreamFactory to create an
* instance of an XMLInputStream
* @param name The file to parse
* @return XMLInputStream the stream to parse
*/
public XMLInputStream getInputStream(String name)
throws XMLStreamException, FileNotFoundException
{
XMLInputStreamFactory factory = XMLInputStreamFactory.newInstance();
XMLInputStream stream = factory.newInputStream(new FileInputStream(name));
return stream;
}
public static void main(String args[])
throws Exception
{
PrintPurchaseOrder printer = new PrintPurchaseOrder();
//
// Create an output stream.
//
XMLOutputStreamFactory factory = XMLOutputStreamFactory.newInstance();
XMLOutputStream output = factory.newOutputStream(new
PrintWriter(System.out,true));
// add the <purchase_order> root element
output.add(ElementFactory.createStartElement("purchase_order"));
output.add(ElementFactory.createCharacterData("\n"));

// add the <name> element
output.add(ElementFactory.createStartElement("name"));
output.add(ElementFactory.createCharacterData("Juliet Shackell"));
output.add(ElementFactory.createEndElement("name"));
output.add(ElementFactory.createCharacterData("\n"));

// add the <item> element along with the id and quantity attributes
output.add(ElementFactory.createStartElement("item"));
output.add(ElementFactory.createAttribute("id","1234"));
output.add(ElementFactory.createAttribute("quantity","2"));
output.add(ElementFactory.createCharacterData("Fabulous Chair"));
output.add(ElementFactory.createEndElement("item"));
output.add(ElementFactory.createCharacterData("\n"));

// add a comment
output.add("<!-- this is a comment-->");
output.add(ElementFactory.createCharacterData("\n"));

// create an input stream from each XML file argument then add it to the output
for (int i=0; i < args.length; i++)
//
// Get an input stream and add it to the output stream
//
output.add(printer.getInputStream(args[i]));

// Finally, end the root "purchase_order" element
output.add(ElementFactory.createEndElement("purchase_order"));
output.add(ElementFactory.createCharacterData("\n"));

//
// Print the results to the screen
//
output.flush();

// Close the output streams
output.close();
}
}

上のプログラムは、次の出力を生成します。

<purchase_order>
<name>Juliet Shackell</name>
<item id="1234" quantity="2">Fabulous Chair</item>
<!-- this is a comment-->
<another_file>
This is from another file.
</another_file>
</purchase_order>

XML出力ストリームの作成

WebLogic XML Streaming APIによりXMLドキュメントを生成する最初の手順の1つは、構築されるドキュメントを入れるための出力ストリームを作成することです。XML出力ストリームの作成方法は、入力ストリームの作成方法と似ています。まず、XMLOutputStreamFactoryのインスタンスを作成し、次にXMLOutputStreamFactory.newOutputStream()メソッドで出力ストリームを作成します。以下に例を示します。

XMLOutputStreamFactory factory = XMLOutputStreamFactory.newInstance();
XMLOutputStream output = factory.newOutputStream(new
PrintWriter(System.out,true));

次の例では、DOMツリーに基づいてXMLOutputStreamを作成する方法を示します。

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setValidating(false);
dbf.setNamespaceAware(true);
Document doc = dbf.newDocumentBuilder().newDocument();
XMLOutputStream out =
XMLOutputStreamFactory.newInstance().newOutputStream(doc);

XMLOutputStreamFactory.newOutputStream()メソッドを使用して、以下の4つのJavaオブジェクトに基づく出力ストリームを作成できます。オブジェクトは、XMLドキュメントの最終形式を何にするか(オペレーティング・システム上のファイル、DOMツリーなど)に応じて決定します。

- java.io.OutputStream

- java.io.Writer

- org.xml.sax.ContentHandler

- org.w3c.dom.Document

出力ストリームへの要素の追加

出力ストリームに要素を追加するには、XMLOutputStream.add(XMLEvent)メソッドを使用します。特定の要素を作成するには、ElementFactoryを使用します。

ElementFactoryインタフェースには、各タイプの要素を作成するためのメソッドがあります。一般的なフォーマットはElementFactory.createXXX()です。XXXは、createStartElement()、createCharacterData()などの特定の要素を表します。StringまたはXMLNameのような名前を渡すことにより、大部分の要素を作成できます。

ヒント:

XMLOutputStreamはXMLを検証しません。

注意:

開始要素を作成するたびに、終了要素もどこかに明示的に作成する必要があります。同じ規則が開始ドキュメントの作成にも適用されます。

たとえば、次のような小さなXMLを作成するとします。

<name>Juliet Shackell</name>

出力ストリームにこの要素を追加するJavaコードは次のようになります。

output.add(ElementFactory.createStartElement("name"));
output.add(ElementFactory.createCharacterData("Juliet Shackell"));
output.add(ElementFactory.createEndElement("name"));
output.add(ElementFactory.createCharacterData("\n"));

最後のcreateCharacterData()メソッドは、出力ストリームに改行文字を追加します。この指定は必須ではありませんが、読みやすいXMLを作成するときに便利です。

出力ストリームの要素への属性の追加

作成した要素に属性を追加するには、XMLOutputStream.add(Attribute)を使用します。特定の属性を作成するには、ElementFactory.createAttribute()メソッドを使用します。

たとえば、次のような小さなXMLを作成するとします。

<item id="1234" quantity="2">Fabulous Chair</item>

出力ストリームにこの要素を追加するJavaコードは次のようになります。

output.add(ElementFactory.createStartElement("item"));
output.add(ElementFactory.createAttribute("id","1234"));
output.add(ElementFactory.createAttribute("quantity","2"));
output.add(ElementFactory.createCharacterData("Fabulous Chair"));
output.add(ElementFactory.createEndElement("item"));
output.add(ElementFactory.createCharacterData("\n"));

注意:

要素への属性の追加は、開始要素を作成した後、対応する終了要素を作成する前に行ってください。そうしない場合、コードは正常にコンパイルされますが、プログラム実行時にエラーが発生します。たとえば、次のコードでは、<item>要素が明示的に終了した後に、この要素に属性が追加されているので、エラーが返されます。

output.add(ElementFactory.createStartElement("item"));
output.add(ElementFactory.createEndElement("item"));
output.add(ElementFactory.createAttribute("id","1234"));
output.add(ElementFactory.createAttribute("quantity","2"));
output.add(ElementFactory.createCharacterData("Fabulous Chair"));
output.add(ElementFactory.createCharacterData("\n"));

出力ストリームへの入力ストリームの追加

XML出力ストリームを作成する際、XMLファイルやDOMツリーのような既存のXMLドキュメントを出力ストリームに追加したいことがあります。これを行うには、まず、そのXMLドキュメントをXML入力ストリームに変換してから、XMLOutputStream.add(XMLInputStream)メソッドを使用して出力ストリームに入力ストリームを追加します。

次の例では、まず、XMLファイルからXML入力ストリームを作成するgetInputStream()というメソッドを示し、その後、このメソッドを使用して作成された入力ストリームを出力プログラムに追加する方法を示します。

/**
* Helper method to get a handle on a stream.
* Takes in a name and returns a stream.  This
* method uses the InputStreamFactory to create an
* instance of an XMLInputStream
* @param name The file to parse
* @return XMLInputStream the stream to parse
*/

public XMLInputStream getInputStream(String name)
throws XMLStreamException, FileNotFoundException
{
XMLInputStreamFactory factory = XMLInputStreamFactory.newInstance();
XMLInputStream stream = factory.newInputStream(new FileInputStream(name));
return stream;
}

....

// create an input stream from each XML file argument then add it to the output
for (int i=0; i < args.length; i++)
//
// Get an input stream and add it to the output stream
//
output.add(printer.getInputStream(args[i]));

出力ストリームの出力

XML出力ストリームを作成元のオブジェクトに出力するには、XMLOutputStream.flush()メソッドを使用します。たとえば、PrintWriterオブジェクトからXML出力ストリームを作成した場合、そのストリームは、flush()メソッドにより標準出力に出力されます。

注意:

DOMツリーに基づいてXMLOutputStreamに書き込む場合、DOMを操作するには、その前にflush()メソッドを実行する必要があります。

次の例では、出力ストリームを出力する方法を示します。

//
// Print the results to the screen
//
output.flush();

出力ストリームのクローズ

プログラミング慣行として、XML出力ストリームでの作業終了時に出力ストリームを明示的にクローズします。出力ストリームをクローズするには、XMLOutputStream.close()メソッドを使用します。以下に例を示します。

// close the output stream
output.close();

Copyright © 2007, 2013, Oracle and/or its affiliates. All rights reserved.