この章の内容は次のとおりです。
この項では、XML検証の様々な方法について説明します。内容は次のとおりです。
この章では、次のテクノロジについて実用的な知識があることを前提にしています。
Document Type Definition(DTD): XML DTDは、XML文書の有効な構造を定義します。
XML Schema言語: XML Schemaは、XML文書の有効な構造を定義します。
これらのテクノロジを十分に理解していない場合や、知識を更新する必要がある場合は、「はじめに」の「関連ドキュメント」にあるXMLの資料を参照してください。
|
関連項目:
|
XML SchemaはW3C標準です。XML Schemaの仕様は次の場所にあります。
http://www.w3.org/TR/xmlschema-0/(W3C XML Schemaの入門書)
http://www.w3.org/TR/xmlschema-1/(XML Schema言語の構造の定義)
http://www.w3.org/TR/xmlschema-2/(XML Schema言語のデータ型の定義)
Oracle XML Schema Processorは、W3CのXML Schema仕様をサポートしています。
DTDは、最初はSGML用に開発されました。XML DTDは、SGMLで使用可能なDTDのサブセットであり、XMLマークアップに対する制約を宣言するためのメカニズムを提供します。XML DTDによって、次のものを指定できます。
XML文書で使用できる要素。
XML要素のコンテンツ・モデル。つまり、要素にデータのみが含まれるか、またはその構造を定義するサブ要素のセットを含むか。DTDでは、サブ要素がオプションと必須のどちらであるか、またサブ要素の出現が1回のみか複数回可能かを定義します。
XML要素の属性。DTDでは、属性がオプションと必須のどちらであるかも指定できます。
XML文書で有効なエンティティ。
XML DTD自体はXMLで記述されているのではなく、XML文書の構造を定義するための、コンテキストに依存しない文法です。DTDは、XML文書内で、またはXML文書とは別のファイルで宣言できます。
検証とは、関連するDTDに対してXML文書が妥当であるかどうかを検証して、構造、要素の使用方法および属性の使用方法がDTDの定義と一致していることを確認するプロセスです。XML文書を処理するアプリケーションでは、検証によって、データと定義が一致することを想定できます。
XDKを使用することにより、検証XMLパーサー(XML文書を解析して、その文書がDTDに対して妥当かどうかを検証するプログラム)を含むアプリケーションを作成できます。DTD検証を実行するパーサーの次の側面に注意してください。
実装に応じて、検証パーサーはエラーの発生時に処理を停止または続行できます。
検証パーサーは、警告およびエラーが発生すると、処理の最後にこれらを要約形式で報告できます。
ほとんどのプロセッサでは検証モードを有効または無効にできますが、いずれの場合もエンティティ定義とDTDのその他の構成メンバーは処理する必要があります。
例7-1に、family.dtdという名前のDTDのコンテンツを示します。このDTDは$ORACLE_HOME/xdk/demo/java/parser/common/にあります。<ELEMENT>タグでは文書内の要素の有効な名称および構造を指定し、<ATTLIST>タグでは要素の有効な属性を指定します。
例7-1 family.dtd
<?xml version="1.0" encoding="UTF-8"?> <!ELEMENT family (member*)> <!ATTLIST family lastname CDATA #REQUIRED> <!ELEMENT member (#PCDATA)> <!ATTLIST member memberid ID #REQUIRED> <!ATTLIST member dad IDREF #IMPLIED> <!ATTLIST member mom IDREF #IMPLIED>
例7-2に、family.xmlという名前のXML文書のコンテンツを示します。このXML文書は$ORACLE_HOME/xdk/demo/java/parser/common/にあります。family.xmlの<!DOCTYPE>要素では、このXML文書がfamily.dtdという名前の外部DTDに準拠することを指定します。
例7-2 family.xml
<?xml version="1.0" standalone="no"?> <!DOCTYPE family SYSTEM "family.dtd"> <family lastname="Smith"> <member memberid="m1">Sarah</member> <member memberid="m2">Bob</member> <member memberid="m3" mom="m1" dad="m2">Joanne</member> <member memberid="m4" mom="m1" dad="m2">Jim</member> </family>
XML Schema定義とも呼ばれるXML Schema言語は、XML構文を使用してXML文書のコンテンツおよび構造を記述するためにW3Cで作成されました。XMLスキーマは、XML Schema言語で記述されたXML文書です。XMLスキーマ文書には、入力XML文書の構造を記述するインスタンス・ドキュメントと呼ばれるルールが含まれています。インスタンス・ドキュメントは、XMLスキーマのルールに準拠する場合のみ有効です。
XML Schema言語では、次のようなことを定義します。
インスタンス・ドキュメントで有効な要素および属性
他の要素の子にすることのできる要素
子要素の順序と数
要素と属性のデータ型
要素と属性のデフォルト値と固定値
検証XMLパーサーは、インスタンス・ドキュメントが関連XMLスキーマのルールに準拠しているかどうかの判断を試行します。XDKを使用することにより、このスキーマ検証を実行する検証パーサーを作成できます。スキーマ検証を実行するパーサーの次の側面に注意してください。
実装に応じて、パーサーはエラーの発生時に処理を停止または続行できます。
パーサーは、警告およびエラーが発生すると、処理の最後にこれらを要約形式で報告できます。
プロセッサは、インスタンス・ドキュメントによって含められたDTDに定義されているエンティティ定義およびその他の構成メンバーを考慮する必要があります。XML Schema言語では、インスタンス・ドキュメントにXMLスキーマとDTDの両方が含まれる場合に何を行う必要があるかは定義されていません。したがって、このような場合のアプリケーションの動作は実装によって決まります。
例7-3に、異なる地域で注文された部品を記述する購入レポートを含むサンプルXML文書を示します。このサンプル・ファイルは、$ORACLE_HOME/xdk/demo/java/schema/report.xmlにあります。
例7-3 report.xml
<purchaseReport xmlns="http://www.example.com/Report" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.com/Report report.xsd" period="P3M" periodEnding="1999-12-31"> <regions> <zip code="95819"> <part number="872-AA" quantity="1"/> <part number="926-AA" quantity="1"/> <part number="833-AA" quantity="1"/> <part number="455-BX" quantity="1"/> </zip> <zip code="63143"> <part number="455-BX" quantity="4"/> </zip> </regions> <parts> <part number="872-AA">Lawnmower</part> <part number="926-AA">Baby Monitor</part> <part number="833-AA">Lapis Necklace</part> <part number="455-BX">Sturdy Shelves</part> </parts> </purchaseReport>
例7-4に、report.xsdという名前のXMLスキーマ文書を示します。この文書は、report.xml の検証に使用できるサンプルXMLスキーマ文書です。XMLスキーマは特に、インスタンス・ドキュメントで有効な要素の名前と、要素に含めることのできるデータ型を定義します。
例7-4 report.xsd
<schema targetNamespace="http://www.example.com/Report"
xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:r="http://www.example.com/Report"
elementFormDefault="qualified">
<annotation>
<documentation xml:lang="ja">
Report schema for Example.com
Copyright 2000 Example.com. All rights reserved.
</documentation>
</annotation>
<element name="purchaseReport">
<complexType>
<sequence>
<element name="regions" type="r:RegionsType">
<keyref name="dummy2" refer="r:pNumKey">
<selector xpath="r:zip/r:part"/>
<field xpath="@number"/>
</keyref>
</element>
<element name="parts" type="r:PartsType"/>
</sequence>
<attribute name="period" type="duration"/>
<attribute name="periodEnding" type="date"/>
</complexType>
<unique name="dummy1">
<selector xpath="r:regions/r:zip"/>
<field xpath="@code"/>
</unique>
<key name="pNumKey">
<selector xpath="r:parts/r:part"/>
<field xpath="@number"/>
</key>
</element>
<complexType name="RegionsType">
<sequence>
<element name="zip" maxOccurs="unbounded">
<complexType>
<sequence>
<element name="part" maxOccurs="unbounded">
<complexType>
<complexContent>
<restriction base="anyType">
<attribute name="number" type="r:SKU"/>
<attribute name="quantity" type="positiveInteger"/>
</restriction>
</complexContent>
</complexType>
</element>
</sequence>
<attribute name="code" type="positiveInteger"/>
</complexType>
</element>
</sequence>
</complexType>
<simpleType name="SKU">
<restriction base="string">
<pattern value="\d{3}-[A-Z]{2}"/>
</restriction>
</simpleType>
<complexType name="PartsType">
<sequence>
<element name="part" maxOccurs="unbounded">
<complexType>
<simpleContent>
<extension base="string">
<attribute name="number" type="r:SKU"/>
</extension>
</simpleContent>
</complexType>
</element>
</sequence>
</complexType>
</schema>
XML Schema言語には、DTD仕様のほとんどの機能が含まれています。XMLスキーマはDTDと同様の目的を果しますが、文書制約の指定の柔軟性が高くなっています。表7-1に、2つの検証メカニズム間で機能の一部を比較します。
表7-1 XMLスキーマとDTDの機能の比較
| 機能 | XMLスキーマ | DTD |
|---|---|---|
|
要素のネスト |
○ |
○ |
|
要素の出現の制約 |
○ |
○ |
|
許可される属性 |
○ |
○ |
|
属性タイプとデフォルト値 |
○ |
○ |
|
XMLでの記述 |
○ |
|
|
名前空間のサポート |
○ |
|
|
組込みデータ型 |
○ |
|
|
ユーザー定義のデータ型 |
○ |
|
|
組込み/インポート |
○ |
|
|
再定義(継承) |
○ |
次に、DTD検証ではなくXMLスキーマ検証を選択する最大の理由を示します。
XML Schema言語では、要素と属性のコンテンツのルールを定義できます。データ型を使用してコンテンツを制御できます。XML Schemaのデータ型では、次のようなアクションを簡単に実行できます。
どの要素にどのデータ型が含まれるかを宣言します。たとえば、ある要素に正の整数が含まれ、別の要素に年が含まれることを宣言します。
データベースから取得したデータを処理します。
10から20までの数値など、データに対する制限を定義します。
MM-DD-YYYY形式の日付など、データ形式を定義します。
文字列から日付など、異なるデータ型間でデータを変換します。
DTDの文法とは異なり、XML Schema言語で記述された文書自体はXMLで記述されています。このため、次のアクションを実行できます。
XMLパーサーを使用したXMLスキーマの解析
XML DOMを使用したXMLスキーマの処理
XSLTを使用したXML文書の変換
他のXMLスキーマでのXMLスキーマの再利用
要素と属性の追加によるXMLスキーマの拡張
同じ文書からの複数のXMLスキーマの参照
Oracle XML Schema ProcessorはSAXベースのXMLスキーマ・バリデータであり、XMLスキーマに対してインスタンス・ドキュメントが妥当かどうかを検証するために使用できます。プロセッサでは、LAXと厳密な検証の両方がサポートされています。
プロセッサは次の方法で使用できます。
XMLパーサーで有効にします。
DOMツリーで使用して、XML文書の全体または一部を検証します。
処理パイプライン(コンテンツ・ハンドラなど)でコンポーネントとして使用します。
要件に応じて、様々な方法でSchema Processorを構成できます。たとえば、次の操作を行うことができます。
固定のXMLスキーマを使用するか、インスタンス・ドキュメントのschemaLocation属性に基づいてスキーマを自動的に構築します。
検証プロセスをより詳細に制御できるようにXMLErrorおよびentityResolverを設定します。
インスタンス・ドキュメントをどの程度検証するかを決定します。表4-1に示した検証モードのいずれかを使用できます。検証のルートとして要素の型を指定することもできます。
次のXDKパッケージは、XMLスキーマを処理するアプリケーションで重要です。
XML解析用のAPIを提供するoracle.xml.parser.v2
XMLスキーマ処理用のAPIを提供するoracle.xml.parser.schema
表7-2に、oracle.xml.parser.schemaパッケージの最も重要なクラスを示します。これらのクラスは、ほとんどのXMLスキーマ・アプリケーションのコアを形成します。
表7-2 oracle.xml.parser.schemaのクラス
| クラス/インタフェース | 説明 | メソッド |
|---|---|---|
|
|
XML Schemaコンポーネント・モデルを表します。 |
主要なメソッドは次のとおりです。
|
|
|
型定義、要素と属性の宣言、グループと属性グループの定義など、ターゲット名前空間内のスキーマ・コンポーネントを表します。 |
主要なメソッドは |
|
|
XMLスキーマ文書から |
主要なメソッドは次のとおりです。
|
|
|
XMLスキーマに対してXMLインスタンス・ドキュメントが妥当かどうかを検証します。登録されている場合、 |
主要なメソッドは次のとおりです。
|
図7-1 に、XML Schema Processorでインスタンス・ドキュメントを検証する基本プロセスを示します。
XML Schema Processorは、次の主要タスクを実行します。
ビルダー(XSDBuilderオブジェクト)が、入力XMLスキーマ文書からXMLスキーマを作成します。インスタンス・ドキュメントおよびスキーマは、特にオペレーティング・システムにファイルとして存在する必要はありませんが、一般にファイルと呼ばれます。これらは、バイト・ストリーム、データベース・レコードのフィールドまたはXML Infosetの情報項目のコレクションとして存在できます。
このタスクには、スキーマ文書のオブジェクトへの解析が含まれます。ビルダーは、スキーマ・オブジェクトを明示的または暗黙的に作成します。
明示的モードでは、プロセッサを起動するときにXMLスキーマを渡します。「外部参照XMLスキーマに対する検証」では、明示的モードでのスキーマ・オブジェクトの作成方法について説明しています。
暗黙的モードでは、スキーマがインスタンス・ドキュメントにより内部的に参照されているため、プロセッサの起動時にXMLスキーマを渡しません。「内部参照XMLスキーマに対する検証」では、暗黙的モードでのスキーマ・オブジェクトの作成方法について説明しています。
XMLスキーマ・バリデータでは、スキーマ・オブジェクトを使用してインスタンス・ドキュメントを検証します。このタスクには、次の手順が含まれます。
SAXパーサーは、インスタンス・ドキュメントをSAXイベントに解析し、これをバリデータに渡します。
バリデータは、SAXイベントを入力として受け取り、これらがスキーマ・オブジェクトに対して妥当かどうかを検証し、無効なXMLコンポーネントが見つかった場合はエラー・メッセージを送信します。
「XMLパーサーでの検証」では、インスタンス・ドキュメントの検証時に使用できる検証モードについて説明しています。XSDBuilderクラスを使用して検証用のスキーマを明示的に設定しない場合は、インスタンス・ドキュメントで正しいxsi:schemaLocation属性がスキーマ・ファイルを指している必要があります。そうでない場合、プログラムは検証を実行しません。プロセッサでエラーが発生した場合は、エラー・メッセージが生成されます。
バリデータは、入力SAXイベント、デフォルト値またはスキーマ検証後の情報をDOMビルダーまたはアプリケーションに送信します。
|
関連項目:
|
XML Schema Processor for Javaのデモ・プログラムは、$ORACLE_HOME/xdk/demo/java/schemaに含まれています。表7-3で、XML Schema Processorのテストに使用できるXMLファイルとプログラムについて説明します。
表7-3 XML Schemaのサンプル・ファイル
| ファイル | 説明 |
|---|---|
cat.xsd |
|
catalogue.xml |
|
catalogue_e.xml |
|
DTD2Schema.java |
このサンプル・プログラムは、DTD(第1引数)をXML Schemaに変換し、これを使用してXMLファイル(第2引数)を検証します。 |
embeded_xsql.xsd |
|
embeded_xsql.xml |
|
juicer1.xml |
|
juicer1.xsd |
|
juicer2.xml |
|
juicer2.xsd |
|
report.xml |
XMLスキーマ |
report.xsd |
|
report_e.xml |
プログラムは、 |
xsddom.java |
このプログラムは、ドキュメントのDOM表現を取得し、 |
xsdent.java |
このプログラムは、 |
xsdent.xml |
このXML文書は書籍を記述します。ファイルは、 |
xsdent.xsd |
このXMLスキーマ文書は、 |
xsdent-1.xsd |
|
xsdproperty.java |
このデモは、複合型または要素宣言に基づいてXML文書を検証するようにXML Schema Processorを構成する方法を示します。 |
xsdsax.java |
このデモは、SAXストリームとして受け取ったXML文書の検証方法を示します。 |
XSDLax.java |
このデモは、 |
XSDSample.java |
このプログラムは、XMLインスタンス・ドキュメントの処理に使用できるサンプル・ドライバです。 |
XSDSetSchema.java |
このプログラムは、 |
サンプル・プログラムのコンパイル方法および実行方法は、同じディレクトリにあるREADMEに示されています。基本手順は次のとおりです。
ディレクトリを$ORACLE_HOME/xdk/demo/java/schemaディレクトリ(UNIXの場合)または%ORACLE_HOME%\xdk\demo\java\schemaディレクトリ(Windowsの場合)に変更します。
コマンドラインでmake(UNIXの場合)またはMake.bat(Windowsの場合)を実行します。
xmlparserv2.jar、xschema.jarおよび現在のディレクトリをCLASSPATHに追加します。これらのJARファイルは$ORACLE_HOME/lib(UNIXの場合)および%ORACLE_HOME%\lib(Windowsの場合)にあります。たとえば、CLASSPATHは、UNIXのtcshシェルで次のように設定できます。
setenv CLASSPATH "$CLASSPATH":$ORACLE_HOME/lib/xmlparserv2.jar:$ORACLE_HOME/lib/schema.jar:.
XML Schema ProcessorにはJDKバージョン1.2以上が必要であり、Java 1.2をサポートしている任意のオペレーティング・システムで使用できます。
ディレクトリに含まれているXMLファイルを使用してサンプル・プログラムを実行します。
次の例では、report.xsdを使用して、report.xmlのコンテンツを検証します。
java XSDSample report.xml java XSDSetSchema report.xsd report.xml
次の例では、Laxモードでインスタンス・ドキュメントを検証します。
java XSDLax embeded_xsql.xsd embeded_xsql.xml
次の例では、cat.xsdを使用して、catalogue.xmlのコンテンツを検証します。
java XSDSample catalogue.xml java XSDSetSchema cat.xsd catalogue.xml
次の例では、エラー・メッセージを生成します。
java XSDSample catalogue_e.xml java XSDSample report_e.xml
次の例では、xsdent.xsdのschemaLocation属性を使用して、XMLスキーマを検証のためにxsdent-1.xsdにリダイレクトします。
java xsdent xsdent.xml xsdent.xsd
次の例では、report.xmlからSAXストリームを生成し、report.xsdで定義されているXMLスキーマに対して妥当かどうかを検証します。
java xsdsax report.xsd report.xml
次の例では、report.xmlのDOM表現を作成し、report.xsdで定義されているXMLスキーマに対して妥当かどうかを検証します。
java xsddom report.xsd report.xml
次の例では、要素宣言または複合型定義から開始する検証を構成します。
java xsdproperty juicer1.xml juicer1.xsd http://www.juicers.org \ juicersType false > juicersType.out java xsdproperty juicer2.xml juicer2.xsd http://www.juicers.org \ Juicers true > juicers_e.out
次の例では、DTD(dtd2schema.dtd)をXMLスキーマに変換し、これを使用してインスタンス・ドキュメント(dtd2schema.xml)を検証します。
java DTD2Schema dtd2schema.dtd dtd2schema.xml
「XML Parserコマンドライン・ユーティリティの使用」では、oraxmlコマンドライン・ユーティリティの実行方法を説明しています。このユーティリティを使用して、XMLスキーマとDTDに対してインスタンス・ドキュメントが妥当かどうかを検証できます。
$ORACLE_HOME/xdk/demo/java/schemaディレクトリに変更します。例7-5に、コマンドラインで次のコマンドを実行することにより、report.xmlがreport.xsdに対して妥当かどうかを検証する方法を示します。
取得される出力は次のとおりです。
The encoding of the input file: UTF-8 The input XML file is parsed without errors using Schema validation mode.
$ORACLE_HOME/xdk/demo/java/parser/commonディレクトリに変更します。例7-6に、コマンドラインで次のコマンドを実行することにより、family.xmlがfamily.dtdに対して妥当かどうかを検証する方法を示します。
取得される出力は次のとおりです。
The encoding of the input file: UTF-8 The input XML file is parsed without errors using DTD validation mode.
この項の内容は次のとおりです。
$ORACLE_HOME/xdk/demo/java/schema/XSDSample.javaプログラムは、暗黙的なXMLスキーマに対して妥当かどうかを検証する方法を示します。XMLスキーマはインスタンス・ドキュメント自体で参照されているため、検証モードは暗黙的です。
この項の手順に従って、oracle.xml.parser.v2.DOMParserクラスのsetValidationMode()メソッドを使用するプログラムを作成します。
インスタンス・ドキュメントの検証に使用するDOMパーサーを作成します。XSDSample.javaの次のコード部分は、DOMParserオブジェクトの作成方法を示します。
public class XSDSample
{
public static void main(String[] args) throws Exception
{
if (args.length != 1)
{
System.out.println("Usage: java XSDSample <filename>");
return;
}
process (args[0]);
}
public static void process (String xmlURI) throws Exception
{
DOMParser dp = new DOMParser();
URL url = createURL(xmlURI);
...
}
...
}
createURL()は、プログラムに引数として渡されるファイル名からURLを構築するヘルパー・メソッドです。
DOMParser.setValidationMode()メソッドを使用して検証DOMパーサーの検証モードを設定します。たとえば、XSDSample.javaはXMLスキーマ検証の指定方法を示します。
dp.setValidationMode(XMLParser.SCHEMA_VALIDATION); dp.setPreserveWhitespace(true);
DOMParser.setErrorStream()メソッドを使用して出力エラー・ストリームを設定します。たとえば、XSDSample.javaはDOMパーサー・オブジェクトのエラー・ストリームを次のように設定します。
dp.setErrorStream (System.out);
DOMParser.parse()メソッドを使用してインスタンス・ドキュメントを検証します。スキーマはインスタンス・ドキュメントにより内部的に参照されているため、XMLスキーマ・オブジェクトを明示的に作成する必要はありません。たとえば、XSDSample.javaはインスタンス・ドキュメントを次のように検証します。
try
{
System.out.println("Parsing "+xmlURI);
dp.parse(url);
System.out.println("The input file <"+xmlURI+"> parsed without errors");
}
catch (XMLParseException pe)
{
System.out.println("Parser Exception: " + pe.getMessage());
}
catch (Exception e)
{
System.out.println("NonParserException: " + e.getMessage());
}
$ORACLE_HOME/xdk/demo/java/schema/XSDSetSchema.javaプログラムは、XMLスキーマを明示的に検証する方法を示します。XSDBuilderクラスを使用して検証用のスキーマを指定するため、検証モードは明示的です。暗黙的な検証の場合とは異なり、スキーマはインスタンス・ドキュメントでは指定されません。
この項の基本手順に従って、oracle.xml.parser.schema.XSDBuilderクラスのbuild()メソッドを使用するJavaプログラムを作成します。
XSDBuilder.build()メソッドを使用して、XMLスキーマ文書からXMLスキーマ・オブジェクトを作成します。XSDSetSchema.javaの次のコード部分は、オブジェクトの作成方法を示します。
public class XSDSetSchema
{
public static void main(String[] args) throws Exception
{
if (args.length != 2)
{
System.out.println("Usage: java XSDSample <schema_file> <xml_file>");
return;
}
XSDBuilder builder = new XSDBuilder();
URL url = createURL(args[0]);
// Build XML Schema Object
XMLSchema schemadoc = (XMLSchema)builder.build(url);
process(args[1], schemadoc);
}
. . .
createURL()メソッドは、コマンドラインで指定されたスキーマ文書ファイル名からURLを構築するヘルパー・メソッドです。
インスタンス・ドキュメントの検証に使用するDOMパーサーを作成します。XSDSetSchema.javaの次のコードは、インスタンス・ドキュメントのファイル名とXMLスキーマ・オブジェクトをprocess()メソッドに渡す方法を示します。
public static void process(String xmlURI, XMLSchema schemadoc)throws Exception{
DOMParser dp = new DOMParser();
URL url = createURL (xmlURI);
. . .
DOMParser.setXMLSchema()メソッドを使用して、検証に使用するスキーマ・オブジェクトを指定します。暗黙的検証モードでは、インスタンス・ドキュメントがすでにスキーマを参照しているため、この手順は不要です。たとえば、XSDSetSchema.javaはスキーマを次のように指定します。
dp.setXMLSchema(schemadoc);
DOMParser.setValidationMode()メソッドを使用してDOMパーサー・オブジェクトの検証モードを設定します。たとえば、XSDSample.javaはXMLスキーマ検証の指定方法を示します。
dp.setValidationMode(XMLParser.SCHEMA_VALIDATION); dp.setPreserveWhitespace(true);
DOMParser.setErrorStream()メソッドを使用してパーサーの出力エラー・ストリームを設定します。たとえば、XSDSetSchema.javaは出力エラー・ストリームを次のように設定します。
dp.setErrorStream (System.out);
DOMParser.parse()メソッドを使用して、インスタンス・ドキュメントがXMLスキーマに対して妥当かどうかを検証します。たとえば、XSDSetSchema.javaには次のコードが含まれます。
try
{
System.out.println("Parsing "+xmlURI);
dp.parse (url);
System.out.println("The input file <"+xmlURI+"> parsed without errors");
}
catch (XMLParseException pe)
{
System.out.println("Parser Exception: " + pe.getMessage());
}
catch (Exception e)
{
System.out.println ("NonParserException: " + e.getMessage());
}
LAXモードでは、文書全体を検証せずに、インスタンス・ドキュメントのXMLコンテンツの一部を検証できます。LAXパーサーは、関連するXMLスキーマで宣言されているインスタンス・ドキュメントの要素に対してプロセッサが検証を実行する必要があることを示します。プロセッサは、スキーマで宣言された要素がインスタンス・ドキュメントに含まれていない場合でも、そのインスタンス・ドキュメントを無効とみなしません。
LAXモードを使用することにより、XMLの検証対象部分に対してのみスキーマを定義できます。$ORACLE_HOME/xdk/demo/java/schema/XSDLax.javaプログラムは、LAX検証の使用方法を示します。このプログラムは、「外部参照XMLスキーマに対する検証」で説明している基本手順を実行します。
ユーザー指定のXMLスキーマ文書から、XMLスキーマ・オブジェクトを作成します。
インスタンス・ドキュメントの検証に使用するDOMパーサーを作成します。
検証に使用するXMLスキーマを指定します。
DOMパーサー・オブジェクトの検証モードを設定します。
パーサーの出力エラー・ストリームを設定します。
DOMParser.parse()をコールすることにより、XMLスキーマに対してインスタンス・ドキュメントが妥当かどうかを検証します。
LAX検証を有効にするには、パーサーの検証モードをSCHEMA_VALIDATIONではなくSCHEMA_LAX_VALIDATIONに設定します。XSDLax.javaの次のコード部分は、この方法を示しています。
dp.setXMLSchema(schemadoc); dp.setValidationMode(XMLParser.SCHEMA_LAX_VALIDATION); dp.setPreserveWhitespace (true); . . .
サンプル・プログラムを次のように実行することにより、LAX検証をテストできます。
java XSDLax embeded_xsql.xsd embeded_xsql.xml
$ORACLE_HOME/xdk/demo/java/schema/xsdsax.javaプログラムは、SAXストリームとして受け取ったXML文書を検証する方法を示します。XSDValidatorをインスタンス化し、SAXパーサーにコンテンツ・ハンドラとして登録します。
この項の手順に従って、SAXストリームからXMLを検証するプログラムを作成します。
XSDBuilder.build()メソッドを起動することにより、ユーザー指定のXMLスキーマ文書からXMLスキーマ・オブジェクトを作成します。次のコード部分は、オブジェクトの作成方法を示します。
XSDBuilder builder = new XSDBuilder(); URL url = XMLUtil.createURL(args[0]); // Build XML Schema Object XMLSchema schemadoc = (XMLSchema)builder.build(url); process(args[1], schemadoc); . . .
createURL()は、コマンドラインで指定されたファイル名からURLを作成するヘルパー・メソッドです。
インスタンス・ドキュメントの検証に使用するSAXパーサー(SAXParserオブジェクト)を作成します。saxxsd.javaの次のコード部分は、XML文書とスキーマ文書へのハンドルをprocess()メソッドに渡します。
process(args[1], schemadoc);...public static void process(String xmlURI, XMLSchema schemadoc)
throws Exception
{
SAXParser dp = new SAXParser();
...
SAXパーサーを構成します。次のコード部分は、XSDBuilder.setValidationMode()メソッドを使用してSAXパーサー・オブジェクトの検証モードを設定します。
dp.setPreserveWhitespace (true); dp.setValidationMode(XMLParser.NONVALIDATING);
バリデータ(XSDValidatorオブジェクト)を作成して構成します。次のコード部分は、この方法を示します。
XMLError err;... err = new XMLError(); ... XSDValidator validator = new XSDValidator(); ... validator.setError(err);
XSDBuilder.setXMLProperty()メソッドを起動することにより、検証に使用するXMLスキーマを指定します。最初の引数はプロパティの名前(fixedSchema)で、2番目の引数はXMLスキーマ・オブジェクトへの参照です。次のコード部分は、この方法を示します。
validator.setXMLProperty(XSDNode.FIXED_SCHEMA, schemadoc); ...
バリデータをパーサーのSAXコンテンツ・ハンドラとして登録します。次のコード部分は、この方法を示します。
dp.setContentHandler(validator); ...
SAXParser.parse()メソッドを起動することにより、インスタンス・ドキュメントがXMLスキーマに対して妥当かどうかを検証します。次のコード部分は、この方法を示します。
dp.parse (url);
$ORACLE_HOME/xdk/demo/java/schema/xsddom.javaプログラムは、ドキュメントのDOM表現を取得し、XSDValidatorオブジェクトを使用してこれを検証することにより、インスタンス・ドキュメントを検証する方法を示します。
xsddom.javaプログラムは次の手順を実行します。
XSDBuilder.build()メソッドを起動することにより、ユーザー指定のXMLスキーマ文書からXMLスキーマ・オブジェクトを作成します。次のコード部分は、オブジェクトの作成方法を示します。
XSDBuilder builder = new XSDBuilder(); URL url = XMLUtil.createURL(args[0]); XMLSchema schemadoc = (XMLSchema)builder.build(url); process(args[1], schemadoc);
createURL()は、コマンドラインで指定されたファイル名からURLを作成するヘルパー・メソッドです。
インスタンス・ドキュメントの検証に使用するDOMパーサー(DOMParserオブジェクト)を作成します。domxsd.javaの次のコード部分は、XML文書とスキーマ文書へのハンドルをprocess()メソッドに渡します。
process(args[1], schemadoc);...public static void process(String xmlURI, XMLSchema schemadoc)
throws Exception
{
DOMParser dp = new DOMParser();
. . .
DOMパーサーを構成します。次のコード部分は、DOMParser.setValidationMode()メソッドを使用してパーサー・オブジェクトの検証モードを設定します。
dp.setPreserveWhitespace (true); dp.setValidationMode(XMLParser.NONVALIDATING); dp.setErrorStream (System.out);
インスタンス・ドキュメントを解析します。次のコード部分は、この方法を示します。
dp.parse (url);
入力文書のDOM表現を取得します。次のコード部分は、この方法を示します。
XMLDocument doc = dp.getDocument();
バリデータ(XSDValidatorオブジェクト)を作成して構成します。次のコード部分は、この方法を示します。
XMLError err;... err = new XMLError(); ... XSDValidator validator = new XSDValidator(); ... validator.setError(err);
XSDBuilder.setXMLProperty()メソッドを起動することにより、検証に使用するスキーマ・オブジェクトを指定します。最初の引数はプロパティの名前(この例ではfixedSchema)で、2番目の引数はスキーマ・オブジェクトへの参照です。次のコード部分は、この方法を示します。
validator.setXMLProperty(XSDNode.FIXED_SCHEMA, schemadoc); . . .
DOMツリーのルート要素(XMLElement)を取得し、検証します。次のコード部分は、この方法を示します。
XMLElement root = (XMLElement)doc.getDocumentElement(); XMLElement copy = (XMLElement)root.validateContent(validator, true); copy.print(System.out);
$ORACLE_HOME/xdk/demo/java/schema/xsdproperty.javaプログラムは、複合型または要素宣言に基づいてXML文書を検証するようにXML Schema Processorを構成する方法を示します。
xsdproperty.javaプログラムは次の手順を実行します。
インスタンス・ドキュメント名、XMLスキーマ名、ルート・ノードの名前空間、ルート・ノードのローカル名、および要素または複合型の指定("true"はルート・ノードが要素宣言であることを意味します)に関するStringオブジェクトを作成します。次のコード部分は、この方法を示します。
String xmlfile = args[0];
String xsdfile = args[1];
...
String ns = args[2]; //namespace for the root node
String nm = args[3]; //root node's local name
String el = args[4]; //true if root node is element declaration,
// otherwise, the root node is a complex type
XSDビルダーを作成し、それを使用してスキーマ・オブジェクトを作成します。次のコード部分は、この方法を示します。
XSDBuilder builder = new XSDBuilder(); URL url = XMLUtil.createURL(xsdfile); XMLSchema schema; ... schema = (XMLSchema) builder.build(url);
ノードを取得します。ノードが要素宣言と複合型のどちらであるかに応じて異なるメソッドを起動します。
ノードが要素宣言である場合は、ローカル名と名前空間をスキーマ・オブジェクトのgetElement()メソッドに渡します。
ノードが要素宣言である場合は、名前空間、ローカル名およびルート複合型をスキーマ・オブジェクトのgetType()メソッドに渡します。
xsdproperty.javaは、次の制御構造を使用します。
QxName qname = new QxName(ns, nm);
...
XSDNode nd;
...
if (el.equals("true"))
{
nd = schema.getElement(ns, nm);
/* process ... */
}
else
{
nd = schema.getType(ns, nm, XSDNode.TYPE);
/* process ... */
}
ノードを取得した後で、新規パーサーを作成し、スキーマをパーサーに設定してスキーマ検証を有効にします。次のコード部分は、この方法を示します。
DOMParser dp = new DOMParser(); URL url = XMLUtil.createURL (xmlURI);
パーサー上のプロパティを設定し、URLを解析します。schemaValidatorProperty()メソッドを次のように起動します。
パーサーのルート要素または型プロパティを完全修飾名に設定します。
最上位レベルの要素宣言では、process1()メソッドで示されているように、プロパティ名をXSDNode.ROOT_ELEMENTに設定し、値をQNameに設定します。
最上位レベルの型定義では、process2()メソッドで示されているように、プロパティ名をXSDNode.ROOT_TYPEに設定し、値をQNameに設定します。
パーサーのルート・ノード・プロパティを要素または複合型ノードに設定します。
要素ノードでは、process3()メソッドで示されているように、プロパティ名をXSDNode.ROOT_NODEに設定し、値をXSDElementノードに設定します。
型ノードでは、process3()メソッドで示されているように、プロパティ名をXSDNode.ROOT_NODEに設定し、値をXSDComplexTypeノードに設定します。
次のコード部分はメソッドの起動順序を示します。
if (el.equals("true"))
{
nd = schema.getElement(ns, nm);
process1(xmlfile, schema, qname);
process3(xmlfile, schema, nd);
}
else
{
nd = schema.getType(ns, nm, XSDNode.TYPE);
process2(xmlfile, schema, qname);
process3(xmlfile, schema, nd);
}
処理メソッドは次のように実装されます。
static void process1(String xmlURI, XMLSchema schema, QxName qname)
throws Exception
{
/* create parser... */
dp.setXMLSchema(schema);
dp.setSchemaValidatorProperty(XSDNode.ROOT_ELEMENT, qname);
dp.setPreserveWhitespace (true);
dp.setErrorStream (System.out);
dp.parse (url);
...
}
static void process2(String xmlURI, XMLSchema schema, QxName qname)
throws Exception
{
/* create parser... */
dp.setXMLSchema(schema);
dp.setSchemaValidatorProperty(XSDNode.ROOT_TYPE, qname);
dp.setPreserveWhitespace (true);
dp.setErrorStream (System.out);
dp.parse (url);
...
}
static void process3(String xmlURI, XMLSchema schema, XSDNode node)
throws Exception
{
/* create parser... */
dp.setXMLSchema(schema);
dp.setSchemaValidatorProperty(XSDNode.ROOT_NODE, node);
dp.setPreserveWhitespace (true);
dp.setErrorStream (System.out);
dp.parse (url);
...
}
oracle.xml.schemavalidator.XSDValidator Beanは、oracle.xml.parser.schema.XSDValidatorクラスをカプセル化し、DOMツリーの検証機能を追加します。パーサーは、インスタンス・ドキュメントとXMLスキーマ文書のDOMツリーを構築し、インスタンス・ドキュメントがスキーマに対して妥当かどうかを検証します。
$ORACLE_HOME/xdk/demo/java/transviewerのXSDValidatorSample.javaプログラムは、XSDValidator Beanの使用方法を示します。
この項の基本手順に従って、XSDValidator Beanを使用するJavaプログラムを作成します。
DOMParser.parse()メソッドを使用してインスタンス・ドキュメントを解析します。XSDValidatorSample.javaの次のコード部分は、この方法を示します。
URL xmlinstanceurl, schemaurl; XMLDocument xmldoc1,xmldoc2; // get the URL for the input files xmlinstanceurl = createURL(args[0]); // Parse the XML Instance document first xmldoc1 = parseXMLDocument(xmlinstanceurl);
createURL()は、ファイル名からURLを作成するヘルパー・メソッドです。parseXMLDocument()メソッドは、次のように、URLを入力として受け取り、DOMParser.parse()メソッドを使用して解析します。
DOMParser parser = new DOMParser(); parser.parse(xmlurl); return parser.getDocument();
DOMParser.parse()メソッドを使用してXMLスキーマ文書を解析します。XSDValidatorSample.javaの次のコードは、この方法を示します。
schemaurl = createURL(args[1]);xmldoc2 = parseXMLDocument(schemaurl);
XSDBuilder.build()メソッドを使用して、解析したXMLスキーマからスキーマ・オブジェクトを作成します。XSDValidatorSample.javaの次のコード部分は、この方法を示します。
XSDBuilder xsdbuild = new XSDBuilder(); . . . xmlschema = (XMLSchema)xsdbuild.build(xmldoc2, createURL(args+"builder"));
XSDValidator.setSchema()メソッドに参照を渡すことにより、検証に使用するスキーマ・オブジェクトを指定します。XSDValidatorSample.javaの次のコード部分は、バリデータを作成し、スキーマを設定します。
XSDValidator xsdval = new XSDValidator(); . . . xsdval.setSchema(xmlschema);
XSDValidator.setError()メソッドを起動することにより、バリデータのエラー出力ストリームを設定します。XSDValidatorSample.javaの次のコード部分は、オブジェクトの作成方法を示します。
Properties p = new Properties(System.getProperties());
p.load(new FileInputStream("demo.properties"));
System.setProperties(p);
. . .
XMLError err = new XMLError();
. . .
err.setErrorHandler(new DocErrorHandler());
. . .
xsdval.setError(err);
インスタンス・ドキュメントへの参照をXSDValidator.validate()メソッドに渡すことにより、インスタンス・ドキュメントがスキーマに対して妥当かどうかを検証します。たとえば、XSDValidatorSample.javaには次のコード部分が含まれます。
xsdval.validate(xmldoc1);
この項の内容は次のとおりです。
XSDBuilderは、スキーマを構築する場合に、schemaLocation属性でURLとして指定された他のスキーマを組み込みまたはインポートすることが必要な場合があります。表7-3で説明したxsdent.javaデモでは、この事例を示しています。xsdent.xmlファイルの文書要素には、次の属性が含まれます。
xsi:schemaLocation = "http://www.somewhere.org/BookCatalogue
xsdent.xsd">
xsdent.xsd文書には、次の要素が含まれます。
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.somewhere.org/BookCatalogue"
xmlns:catd = "http://www.somewhere.org/Digest"
xmlns:cat = "http://www.somewhere.org/BookCatalogue"
elementFormDefault="qualified">
<import namespace = "http://www.somewhere.org/Digest"
schemaLocation = "xsdent-1.xsd" />
場合によっては、<import>で指定したスキーマの場所をオーバーライドし、必要なスキーマ文書をビルダーに提供することが必要になります。たとえば、スキーマ文書を外部Webサイトからダウンロードし、それをデータベースに格納する場合があります。このような場合は、XSDBuilderにエンティティ・リゾルバを設定できます。XSDBuilderは、スキーマの場所をリゾルバに渡します。リゾルバは、InputStream、ReaderまたはURLをInputSourceとして戻します。ビルダーは、InputSourceからスキーマ文書を読み取ることができます。
xsdent.javaプログラムは、エンティティ・リゾルバを使用してスキーマの場所をオーバーライドする方法を示します。EntityResolverインタフェースを実装し、エンティティ・リゾルバをインスタンス化し、それをXMLスキーマ・ビルダーに設定する必要があります。デモ・コードでは、sampleEntityResolver1はInputSourceをInputStreamとして戻しますが、sampleEntityResolver2はInputSourceをURLとして戻します。
次の基本手順に従います。
新規XMLスキーマ・ビルダーを次のように作成します。
XSDBuilder builder = new XSDBuilder();
ビルダーをエンティティ・リゾルバに設定します。エンティティ・リゾルバは、EntityResolverインタフェースを実装するクラスです。リゾルバの目的は、XMLリーダーが、外部エンティティを組み込む前に、それらのエンティティをインターセプトできるようにすることです。次のコード部分は、エンティティ・リゾルバを作成し、それをビルダーに設定します。
builder.setEntityResolver(new sampleEntityResolver1());
sampleEntityResolver1クラスは、resolveEntity()メソッドを実装します。このメソッドを使用して、外部システム識別子をローカルURIにリダイレクトできます。このソース・コードは次のようになります。
class sampleEntityResolver1 implements EntityResolver
{
public InputSource resolveEntity (String targetNS, String systemId)
throws SAXException, IOException
{
// perform any validation check if needed based on targetNS & systemId
InputSource mySource = null;
URL u = XMLUtil.createURL(systemId);
// Create input source with InputStream as input
mySource = new InputSource(u.openStream());
mySource.setSystemId(systemId);
return mySource;
}
}
sampleEntityResolver1はInputSourceをストリームで初期化することに注意してください。
XMLスキーマ・オブジェクトを作成します。この方法を示すコードは次のとおりです。
schemadoc = builder.build(url);
XMLスキーマに対してインスタンス・ドキュメントが妥当かどうかを検証します。プログラムは次の文を実行します。
process(xmlfile, schemadoc);
process()メソッドはDOMパーサーを作成して構成し、parse()メソッドを起動します。メソッドは次のように実装されます。
public static void process(String xmlURI, Object schemadoc)
throws Exception
{
DOMParser dp = new DOMParser();
URL url = XMLUtil.createURL (xmlURI);
dp.setXMLSchema(schemadoc);
dp.setValidationMode(XMLParser.SCHEMA_VALIDATION);
dp.setPreserveWhitespace (true);
dp.setErrorStream (System.out);
try {
dp.parse (url);
...
}
XML Schema言語の機能と柔軟性を利用して、既存のDTDをXML Schema文書に変換できます。XDK APIを使用して、この変換を実行できます。
$ORACLE_HOME/xdk/demo/java/schema/DTD2Schema.javaプログラムは、DTDの変換方法を示します。プログラムは次のようにテストできます。
java DTD2Schema dtd2schema.dtd dtd2schema.xml
次の基本手順に従って、DTDをXMLスキーマ文書に変換します。
DOMParser.parseDTD()メソッドを使用してDTDを解析します。DTD2Schema.javaの次のコード部分は、DTDオブジェクトの作成方法を示します。
XSDBuilder builder = new XSDBuilder(); URL dtdURL = createURL(args[0]); DTD dtd = getDTD(dtdURL, "abc");
getDTD()メソッドは次のように実装されます。
private static DTD getDTD(URL dtdURL, String rootName)
throws Exception
{
DOMParser parser = new DOMParser();
DTD dtd;
parser.setValidationMode(true);
parser.setErrorStream(System.out);
parser.showWarnings(true);
parser.parseDTD(dtdURL, rootName);
dtd = (DTD)parser.getDoctype();
return dtd;
}
DTD.convertDTD2Sdhema()メソッドを使用して、DTDをXMLスキーマのDOMツリーに変換します。DTD2Schema.javaの次のコード部分は、この方法を示します。
XMLDocument dtddoc = dtd.convertDTD2Schema();
XMLDocument.print()メソッドを使用して、XMLスキーマのDOMツリーを出力ストリームに書き出します。DTD2Schema.javaの次のコード部分は、この方法を示します。
FileOutputStream fos = new FileOutputStream("dtd2schema.xsd.out");
dtddoc.print(fos);
XSDBuilder.build()メソッドを使用して、スキーマのDOMツリーからXMLスキーマ・オブジェクトを作成します。DTD2Schema.javaの次のコード部分は、この方法を示します。
XMLSchema schemadoc = (XMLSchema)builder.build(dtddoc, null);
DOMParser.parse()メソッドを使用して、インスタンス・ドキュメントがXMLスキーマに対して妥当かどうかを検証します。DTD2Schema.javaの次のコード部分は、この方法を示します。
validate(args[1], schemadoc);
validate()メソッドは次のように実装されます。
DOMParser dp = new DOMParser();
URL url = createURL (xmlURI);
dp.setXMLSchema(schemadoc);
dp.setValidationMode(XMLParser.SCHEMA_VALIDATION);
dp.setPreserveWhitespace (true);
dp.setErrorStream (System.out);
try
{
System.out.println("Parsing "+xmlURI);
dp.parse (url);
System.out.println("The input file <"+xmlURI+"> parsed without errors");
}
...