Caché SAX パーサの使用法のカスタマイズ
Caché で XML ドキュメントを読み取るときは、Caché SAX (Simple API for XML) パーサが使用されます。この章では、Caché SAX パーサを制御するためのオプションを説明します。以下のトピックについて説明します。
-
検証などのためにパーサ・フラグを設定する方法
-
目的のドキュメント・イベント (要素の開始、DTD の開始など) を表すマスクの指定方法
Caché SAX パーサについて
Caché SAX パーサは、Caché により XML ドキュメントが読み取られるたびに使用されます。
これはイベント駆動型の XML パーサです。このパーサは XML ファイルを読み取り、目的の項目 (XML 要素の開始、DTD の開始など) が見つかったときに、コールバックを発行します。
(より正確に言うと、パーサはコンテンツ・ハンドラと連携し、コンテンツ・ハンドラがコールバックを発行します。この区別は、SAX インタフェースをカスタマイズする場合にのみ重要です。詳細は、この章後半の “カスタム・コンテンツ・ハンドラの作成” を参照してください。)
このパーサでは、XML 1.0 の推奨や関連する多数の標準に準拠する標準 Xerces-C++ ライブラリが使用されます。これらの標準のリストについては、http://xml.apache.org/xerces-c/Opens in a new tab を参照してください。
使用可能なパーサ・オプション
SAX パーサの動作は、以下の方法で制御できます。
-
フラグを設定して、実行する検証や処理の種類を指定します。
パーサは、ドキュメントが適格な形式の XML ドキュメントであるかどうかを常にチェックします。
-
目的のイベント (つまり、パーサに検出させる項目) を指定します。このためには、目的のイベントを示すマスクを指定します。
-
ドキュメント検証の基準となるスキーマ仕様を指定します。
-
エンティティの解析は、特殊な目的を持つエンティティ・リゾルバを使用することで無効にできます。
-
エンティティの解析用にタイムアウト時間を指定できます。
-
パーサがドキュメントの任意のエンティティに対する定義を検出する方法を制御する必要がある場合は、より一般的なカスタム・エンティティ・リゾルバを指定します。
-
ある URL に存在するソース・ドキュメントにアクセスする場合は、%Net.HttpRequestOpens in a new tab のインスタンスとして、Web サーバに送信する要求を指定することができます。
%Net.HttpRequestOpens in a new tab の詳細は、"Caché インターネット・ユーティリティの使用法" のドキュメントを参照してください。または、%Net.HttpRequestOpens in a new tab のクラス・ドキュメントを参照してください。
-
カスタム・コンテンツ・ハンドラを指定することができます。
-
HTTPS を使用できます。
使用可能なオプションは、Caché SAX パーサをどのように使用しているかによって異なります。以下のテーブルに概略を示します。
オプション | %XML.ReaderOpens in a new tab | %XML.TextReaderOpens in a new tab | %XML.XPATH.DocumentOpens in a new tab | %XML.SAX.ParserOpens in a new tab |
---|---|---|---|---|
パーサ・フラグの指定 | サポートされる | サポートされる | サポートされる | サポートされる |
目的の解析イベント (要素の開始、要素の終了、コメントなど) の指定 | サポートされない | サポートされる | サポートされない | サポートされる |
スキーマ仕様の指定 | サポートされる | サポートされる | サポートされる | サポートされる |
エンティティの解析の無効化、またはエンティティの解析のカスタマイズ | サポートされる | サポートされる | サポートされる | サポートされる |
カスタム HTTP 要求の指定 (URL を解析する場合) | サポートされない | サポートされる | サポートされない | サポートされる |
コンテンツ・ハンドラの指定 | サポートされない | サポートされない | サポートされない | サポートされる |
HTTPS の場所でのドキュメントの解析 | サポートされる | サポートされない | サポートされない | サポートされる |
HTTPS の場所でのエンティティの解決 | サポートされない | サポートされない | サポートされない | サポートされる |
パーサ・オプションの指定
パーサの動作の指定方法は、Caché SAX パーサの使い方によって異なります。
-
%XML.ReaderOpens in a new tab を使用している場合は、リーダ・インスタンスの Timeout、SAXFlags、SAXSchemaSpec、および EntityResolver プロパティを設定できます。以下はその例です。
#include %occInclude #include %occSAX // set the parser options we want Set flags = $$$SAXVALIDATION + $$$SAXNAMESPACES + $$$SAXNAMESPACEPREFIXES + $$$SAXVALIDATIONSCHEMA Set reader=##class(%XML.Reader).%New() Set reader.SAXFlags=flags
これらのマクロは、%occSAX.inc インクルード・ファイルで定義されています。
-
それ以外の場合は、使用しているメソッドの引数を指定します。以下はその例です。
#include %occInclude #include %occSAX //set the parser options we want Set flags = $$$SAXVALIDATION + $$$SAXNAMESPACES + $$$SAXNAMESPACEPREFIXES + $$$SAXVALIDATIONSCHEMA Set status=##class(%XML.TextReader).ParseFile(myfile,.doc,,flags)
関連するメソッドの引数リストに関する詳細は、以下の章またはセクションを参照してください。
-
%XML.ReaderOpens in a new tab については、“Caché オブジェクトへの XML のインポート” の章を参照してください。
-
%XML.TextReaderOpens in a new tab については、“%XML.TextReader の使用” の章を参照してください。
-
%XML.XPATH.DocumentOpens in a new tab については、“XPath 式の評価” の章を参照してください。
-
%XML.SAX.ParserOpens in a new tab については、この章で後述する “カスタム・コンテンツ・ハンドラの作成” を参照してください。
または、このクラスのドキュメントを参照してください。
-
パーサ・フラグの設定
%occSAX.inc インクルード・ファイルには、Xerces パーサにより実行される検証を制御するために使用されるフラグのリストが含まれます。基本的なフラグは以下のとおりです。
-
$$$SAXVALIDATION — スキーマ検証を実行するかどうかを指定します。このフラグがオン (既定値) の場合、検証エラーがすべて報告されます。
-
$$$SAXNAMESPACES — ネームスペースを認識するかどうかを指定します。このフラグがオン (既定値) の場合、パーサによりネームスペースが処理されます。このフラグがオフの場合は、Caché は、%XML.SAX.ContentHandlerOpens in a new tab の startElement() コールバックで、要素の localname を空文字列に設定します。
-
$$$SAXNAMESPACEPREFIXES — ネームスペースの接頭語を処理するかどうかを指定します。このフラグがオンの場合、ネームスペースの宣言に使用された元の接頭語付きの名前と属性がパーサから報告されます。既定では、このフラグはオフです。
-
$$$SAXVALIDATIONDYNAMIC — 検証を動的に実行するかどうかを指定します。このフラグがオン (既定値) の場合、検証は文法が指定されている場合のみ実行されます。
-
$$$SAXVALIDATIONSCHEMA — スキーマに対する検証を実行するかどうかを指定します。このフラグがオン (既定値) の場合、スキーマが指定されていれば、それに対する検証が実行されます。
-
$$$SAXVALIDATIONSCHEMAFULLCHECKING — 時間のかかるチェックや、大量のメモリを消費するチェックを含め、完全なスキーマ制約チェックを実行するかどうかを指定します。このフラグがオンの場合、制約チェックがすべて行われます。既定では、このフラグはオフです。
-
$$$SAXVALIDATIONREUSEGRAMMAR — 同じ Caché プロセスで、これ以降、行われる解析で再利用するために文法をキャッシュしておくかどうかを指定します。既定では、このフラグはオフです。
-
$$$SAXVALIDATIONPROHIBITDTDS — パーサが DTD を検出した場合にエラーをスローする特殊フラグ。DTD の処理を避ける必要がある場合は、このフラグを使用します。このフラグを使用するには、%XML.SAX.ParserOpens in a new tab のさまざまな解析メソッドに渡される解析フラグに値 $$$SAXVALIDATIONPROHIBITDTDS を明示的に追加する必要があります。
次のフラグは、複数の基本フラグを使いやすく組み合わせたものです。
-
$$$SAXDEFAULTS — SAX の既定値に相当します。
-
$$$SAXFULLDEFAULT — SAX の既定値、およびネームスペース接頭語を処理するためのオプションに相当します。
-
$$$SAXNOVALIDATION — スキーマの検証は行いませんが、ネームスペースとネームスペースの接頭語を認識します。SAX パーサは、ドキュメントが適格な形式の XML ドキュメントであるかどうかを常にチェックします。
詳細は、%occSAX.inc を参照してください。このファイルには、このような種類の検証の詳細へのリンクも用意されています。
次の部分は、パーサ・オプションを組み合わせる方法を示しています。
...
#include %occInclude
#include %occSAX
...
;; set the parser options we want
set opt = $$$SAXVALIDATION
+ $$$SAXNAMESPACES
+ $$$SAXNAMESPACEPREFIXES
+ $$$SAXVALIDATIONSCHEMA
...
set status=##class(%XML.TextReader).ParseFile(myfile,.doc,,opt)
//check status
if $$$ISERR(status) {do $System.Status.DisplayError(status) quit}
イベント・マスクの指定
%occSAX.inc インクルード・ファイルにも、処理の対象となるイベント・コールバックを指定するためのフラグのリストが記載されています。パフォーマンス上の理由から、必要なコールバックのみ処理することをお勧めします。マスクを指定する必要があるかどうかは、Caché SAX パーサの呼び出しに使用するクラスによって異なります。
-
%XML.TextReaderOpens in a new tab では、既定値は $$$SAXCONTENTEVENTS です。コメント以外のイベント・コールバックがすべて処理されます。
-
%XML.SAX.ParserOpens in a new tab では、既定値は 0 で、これはパーサにより、コンテンツ・ハンドラの Mask() メソッドが呼び出されることを表します。このメソッドは、カスタマイズされたイベント・コールバックをすべて検出して、マスクを計算します。処理されるのはこれらのイベントのみです。カスタム・コンテンツ・ハンドラを作成した場合は、%XML.SAX.ParserOpens in a new tab を使用します。詳細は、この章後半の、“カスタム・コンテンツ・ハンドラの作成” を参照してください。
基本的なフラグ
基本的なフラグは以下のとおりです。
-
$$$SAXSTARTDOCUMENT — ドキュメントを開始したときにコールバックを発行するようにパーサに指示します。
-
$$$SAXENDDOCUMENT — ドキュメントを終了したときにコールバックを発行するようにパーサに指示します。
-
$$$SAXSTARTELEMENT — 要素の先頭を見つけたときにコールバックを発行するようにパーサに指示します。
-
$$$SAXENDELEMENT — 要素の末尾を見つけたときにコールバックを発行するようにパーサに指示します。
-
$$$SAXCHARACTERS — 文字を見つけたときにコールバックを発行するようにパーサに指示します。
-
$$$SAXPROCESSINGINSTRUCTION — プロセス指示を見つけたときにコールバックを発行するようにパーサに指示します。
-
$$$SAXSTARTPREFIXMAPPING — 接頭マッピングの先頭を見つけたときにコールバックを発行するようにパーサに指示します。
-
$$$SAXENDPREFIXMAPPING — 接頭マッピングの末尾を見つけたときにコールバックを発行するようにパーサに指示します。
-
$$$SAXIGNORABLEWHITESPACE — 無視可能な空白を見つけたときにコールバックを発行するようにパーサに指示します。これは、ドキュメントが DTD を持ち、検証が有効になっている場合にのみ適用されます。
-
$$$SAXSKIPPEDENTITY — スキップされたエンティティを見つけたときにコールバックを発行するようにパーサに指示します。
-
$$$SAXCOMMENT — コメントを見つけたときにコールバックを発行するようにパーサに指示します。
-
$$$SAXSTARTCDATA — CDATA セクションの先頭を見つけたときにコールバックを発行するようにパーサに指示します。
-
$$$SAXENDCDATA — CDATA セクションの末尾を見つけたときにコールバックを発行するようにパーサに指示します。
-
$$$SAXSTARTDTD — DTD の先頭を見つけたときにコールバックを発行するようにパーサに指示します。
-
$$$SAXENDDTD — DTD の末尾を見つけたときにコールバックを発行するようにパーサに指示します。
-
$$$SAXSTARTENTITY — エンティティの先頭を見つけたときにコールバックを発行するようにパーサに指示します。
-
$$$SAXENDENTITY — エンティティの末尾を見つけたときにコールバックを発行するようにパーサに指示します。
便利な組み合わせフラグ
次のフラグは、複数の基本フラグを使いやすく組み合わせたものです。
-
$$$SAXCONTENTEVENTS — “コンテンツ”を含むイベントすべてに対してコールバックを発行するようにパーサに指示します。
-
$$$SAXLEXICALEVENT — 言語イベントすべてに対してコールバックを発行するようにパーサに指示します。
-
$$$SAXALLEVENTS — すべてのイベントに対してコールバックを発行するようにパーサに指示します。
1 つのマスクへのフラグの組み合わせ
次の部分は、複数のフラグを 1 つのマスクにまとめる方法を示しています。
...
#include %occInclude
#include %occSAX
...
// set the mask options we want
set mask = $$$SAXSTARTDOCUMENT
+ $$$SAXENDDOCUMENT
+ $$$SAXSTARTELEMENT
+ $$$SAXENDELEMENT
+ $$$SAXCHARACTERS
...
// create a TextReader object (doc) by reference
set status = ##class(%XML.TextReader).ParseFile(myfile,.doc,,,mask)
スキーマ・ドキュメントの指定
ドキュメント・ソースの検証の基準となるスキーマ仕様を指定します。次のように、ネームスペース/URL のペアをコンマで区切って指定したリストを含む文字列を指定してください。
"namespace URL,namespace URL,namespace URL,..."
ここで、namespace は (ネームスペース接頭語ではなく) XML ネームスペースであり、URL はネームスペースのスキーマ・ドキュメントの位置を表す URL です。ネームスペースと URL の値の間は、1 つの空白文字で区切られています。例えば、以下は 1 つのネームスペースが含まれたスキーマ仕様を示しています。
"http://www.myapp.org http://localhost/myschemas/myapp.xsd"
以下は 2 つのネームスペースが含まれたスキーマ仕様を示しています。
"http://www.myapp.org http://localhost/myschemas/myapp.xsd,http://www.other.org http://localhost/myschemas/other.xsd"
エンティティの解析の無効化
検証を無効にするように SAX フラグを設定した場合でも、SAX パーサは外部エンティティを解析しようとします。これは、対象のエンティティの場所によっては時間のかかる操作になることがあります。
クラス %XML.SAX.NullEntityResolverOpens in a new tab は、常に空のストリームを返すエンティティ・リゾルバを実装します。エンティティの解析を無効にする場合は、このクラスを使用します。具体的には、XML ドキュメントの読み取りの際は、エンティティ・リゾルバとして %XML.SAX.NullEntityResolverOpens in a new tab のインスタンスを使用します。以下はその例です。
Set resolver=##class(%XML.SAX.NullEntityResolver).%New()
Set reader=##class(%XML.Reader).%New()
Set reader.EntityResolver=resolver
Set status=reader.OpenFile(myfile)
...
この変更によって外部エンティティの解析はすべて無効になるため、この技法を使用すると、XML ドキュメント内のすべての外部 DTD およびスキーマ参照も無効になります。
カスタム・エンティティの解析実行
XML ドキュメントには、外部 DTD または他のエンティティへの参照が含まれている場合があります。既定では、Caché は、これらのエンティティのソース・ドキュメントを見つけて、それらを解析しようとします。Caché による外部エンティティの解析方法を制御するには、以下の手順を使用します。
-
エンティティ・リゾルバ・クラスを定義します。
このクラスは、%XML.SAX.EntityResolverOpens in a new tab クラスを拡張し、resolveEntity() メソッドを実装する必要があります。このメソッドには以下のシグニチャがあります。
method resolveEntity(publicID As %Library.String, systemID As %Library.String) as %Library.Integer
このメソッドは、XML プロセッサが外部エンティティ (DTD など) への参照を検出するたびに呼び出されます。publicID と systemID は、そのエンティティのパブリック識別子文字列とシステム識別子文字列です。
このメソッドは、エンティティまたはドキュメントを取得し、それをストリームとして返してから、そのストリームを %XML.SAX.StreamAdapterOpens in a new tab のインスタンスにラップする必要があります。このクラスは、ストリームの特性の決定に必要なメソッドを提供します。
エンティティを解析できない場合、メソッドでは、$$$NULLOREF を返して、SAX パーサにエンティティを解析できないことを伝える必要があります。
Important:メソッド・シグニチャでは返り値が %Library.IntegerOpens in a new tab であることが示されているにもかかわらず、メソッドは、%XML.SAX.StreamAdapterOpens in a new tab またはそのクラスのサブクラスのインスタンスを返す必要があります。
また、外部エンティティを参照する識別子はドキュメントに指定されているように常に resolveEntity() メソッドに渡されます。特に、そのような識別子が相対 URL を使用する場合、その識別子は相対 URL として渡されます。これは、参照ドキュメントの実際の場所が resolveEntity() メソッドに渡されないことを意味し、エンティティを解決できません。このようなシナリオでは、カスタムのエンティティ・リゾルバではなく既定のエンティティ・リゾルバを使用してください。
エンティティ・リゾルバ・クラスの例は、%XML.SAX.EntityResolverOpens in a new tab のソース・コードを参照してください。
-
XML ドキュメントを読み取る場合は、以下の手順を実行します。
-
エンティティ・リゾルバ・クラスのインスタンスを作成します。
-
XML ドキュメントを読み取る場合は、この章で前述の “パーサ・オプションの指定” で説明しているように、そのインスタンスを使用します。
-
前のセクション “エンティティの解析の無効化” も参照してください。%XML.SAX.NullEntityResolverOpens in a new tab (そのセクションで説明しています) は %XML.SAX.EntityResolverOpens in a new tab のサブクラスであることに注意してください。
例 1
例えば、以下の XML ドキュメントを考えてみます。
<?xml version="1.0" ?>
<!DOCTYPE html SYSTEM "c://temp/html.dtd">
<html>
<head><title></title></head>
<body>
<p>Some < xhtml-content > with custom entities &entity1; and &entity2;.</p>
<p>Here is another paragraph with &entity1; again.</p>
</body></html>
このドキュメントでは、以下の DTD を使用します。
<!ENTITY entity1
PUBLIC "-//WRC//TEXT entity1//EN"
"http://www.intersystems.com/xml/entities/entity1">
<!ENTITY entity2
PUBLIC "-//WRC//TEXT entity2//EN"
"http://www.intersystems.com/xml/entities/entity2">
<!ELEMENT html (head, body)>
<!ELEMENT head (title)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT body (p)>
<!ELEMENT p (#PCDATA)>
このドキュメントを読み取るには、以下のようなカスタム・エンティティ・リゾルバが必要になります。
Class CustomResolver.Resolver Extends %XML.SAX.EntityResolver
{
Method resolveEntity(publicID As %Library.String, systemID As %Library.String) As %Library.Integer
{
Try {
Set res=##class(%Stream.TmpBinary).%New()
//check if we are here to resolve a custom entity
If systemID="http://www.intersystems.com/xml/entities/entity1"
{
Do res.Write("Value for entity1")
Set return=##class(%XML.SAX.StreamAdapter).%New(res)
}
Elseif systemID="http://www.intersystems.com/xml/entities/entity2"
{
Do res.Write("Value for entity2")
Set return=##class(%XML.SAX.StreamAdapter).%New(res)
}
Else //otherwise call the default resolver
{
Set res=##class(%XML.SAX.EntityResolver).%New()
Set return=res.resolveEntity(publicID,systemID)
}
}
Catch
{
Set return=$$$NULLOREF
}
Quit return
}
}
以下のクラスには、前述のファイルを解析してカスタム・リゾルバを使用するデモ・メソッドが含まれています。
Include (%occInclude, %occSAX)
Class CustomResolver.ParseFileDemo
{
ClassMethod ParseFile()
{
Set res= ##class(CustomResolver.Resolver).%New()
Set file="c:/temp/html.xml"
Set parsemask=$$$SAXALLEVENTS+$$$SAXERROR
Set status=##class(%XML.TextReader).ParseFile(file,.textreader,res,,parsemask,,0)
If $$$ISERR(status) {Do $system.OBJ.DisplayError(status) Quit }
Write !,"Parsing the file ",file,!
Write "Custom entities in this file:"
While textreader.Read()
{
If textreader.NodeType="entity"{
Write !, "Node:", textreader.seq
Write !," name: ", textreader.Name
Write !," value: ", textreader.Value
}
}
}
}
以下に、ターミナル・セッションでのこのメソッドの出力を示します。
GXML>d ##class(CustomResolver.ParseFileDemo).ParseFile()
Parsing the file c:/temp/html.xml
Custom entities in this file:
Node:13
name: entity1
value: Value for entity1
Node:15
name: entity2
value: Value for entity2
Node:21
name: entity1
value: Value for entity1
例 2
例として、以下のような XML ドキュメントを読み取る必要があると想定してみましょう (c:\cachesys が Caché のインストール先ディレクトリであると仮定します。ご使用のシステムでの実際の場所については、"Caché インストール・ガイド" の “Caché の既定のインストール・ディレクトリ” を参照してください)。
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"c:\cachesys\csp\docbook\doctypes\docbook\docbookx.dtd">
この場合、resolveEntity メソッドは、-//OASIS//DTD DocBook XML V4.1.2//EN に設定された publicId と、c:\cachesys\csp\docbook\doctypes\docbook\docbookx.dtd に設定された systemId で実行されます。
resolveEntity メソッドは、外部エンティティに対する正確なソースを決定し、これをストリームとして返してから、このストリームを %XML.StreamAdaptor のインスタンスにラップします。XML パーサは、この特別なストリームからエンティティ定義を読み取ります。
この例は、Caché ライブラリの %XML.CatalogOpens in a new tab クラスと %XML.CatalogResolverOpens in a new tab クラスを参照してください。%XML.CatalogOpens in a new tab クラスは、パブリック識別子とシステム識別子を URL と関連させる、単純なデータベースを定義します。%XML.CatalogResolverOpens in a new tab クラスは、このデータベースを使用して、与えられた識別子に対する URL を検索する、エンティティ・リゾルバ・クラスです。%XML.CatalogOpens in a new tab クラスは、SGML 形式のカタログ・ファイルから、このデータベースをロードできます。このファイルは、識別子を標準形式で URL にマップします。
カスタム・コンテンツ・ハンドラの作成
Caché SAX パーサを直接呼び出す場合、自分固有のニーズに合わせて、カスタム・コンテンツ・ハンドラを作成することができます。このセクションでは、以下の項目について説明します。
カスタム・コンテンツ・ハンドラの作成の概要
Caché SAX パーサによる XML のインポートおよび処理方法をカスタマイズするには、カスタム SAX コンテンツ・ハンドラを作成して使用します。具体的には %XML.SAX.ContentHandlerOpens in a new tab のサブクラスを作成します。次に、その新しいクラスで、要求されたアクションを実行するために、必要に応じて、既定のメソッドをオーバーライドします。XML ドキュメントを解析するには、引数として、新しいコンテンツ・ハンドラを使用します。このためには、%XML.SAX.ParserOpens in a new tab クラスの解析メソッドを使用します。
以下の図は、この操作の詳細です。
カスタム・インポート・メカニズムを作成して使用するプロセスは以下のとおりです。
-
%XML.SAX.ContentHandlerOpens in a new tab から派生するクラスを生成します。
-
このクラスに、オーバーライドしたいメソッドをインクルードし、必要に応じて、新しい定義を追加します。
-
%XML.SAX.ParserOpens in a new tab クラスの解析メソッド (ParseFile()、ParseStream()、ParseString()、ParseURL()) の 1 つを使用して、XML ドキュメントを読み取るクラス・メソッドを記述します。
この解析メソッドを呼び出すときには、引数として、このカスタム・コンテンツ・ハンドラを指定します。
カスタマイズ可能な SAX コンテンツ・ハンドラのメソッド
%XML.SAX.ContentHandlerOpens in a new tab クラスは、指定された時間に、特定のメソッドを自動的に実行します。これらのメソッドをオーバーライドして、コンテンツ・ハンドラの動作をカスタマイズすることができます。
イベントへの応答
%XML.SAX.ContentHandlerOpens in a new tab クラスは XML ファイルを解析し、XML ファイルの特定の場所に到達したとき、イベントを生成します。実行されるメソッドは、イベントにより異なります。これらのメソッドは以下のとおりです。
-
OnPostParse() — XML 解析が完了したときにトリガされる
-
characters() — 文字データからトリガされる
-
comment() — コメントからトリガされる
-
endCData() — CDATA セクションの最後によってトリガされる
-
endDocument() — ドキュメントの最後によってトリガされる
-
endDTD() — DTD の最後によってトリガされる
-
endElement() — 要素の最後によってトリガされる
-
endEntity() — エンティティの最後によってトリガされる
-
endPrefixMapping() — ネームスペース接頭マッピングの最後によってトリガされる
-
ignorableWhitespace() — 要素コンテンツ内の無視可能な空白によってトリガされる
-
processingInstruction() — XML 処理命令によってトリガされる
-
skippedEntity() — スキップされたエンティティによってトリガされる
-
startCData() — CDATA セクションの最初によってトリガされる
-
startDocument() — ドキュメントの最初によってトリガされる
-
startDTD() — DTD の最初によってトリガされる
-
startElement() — 要素の最初によってトリガされる
-
startEntity() — エンティティの最初によってトリガされる
-
startPrefixMapping() — ネームスペース接頭マッピングの開始によってトリガされる
これらのメソッドは既定では空ですが、カスタム・コンテンツ・ハンドラでオーバーライドできます。期待される引数リストと返り値の詳細は、%XML.SAX.ContentHandlerOpens in a new tab クラスのドキュメントを参照してください。
エラー処理
%XML.SAX.ContentHandlerOpens in a new tab クラスも、特定のエラーが発生したときにメソッドを実行します。
-
error() — リカバリ可能なパーサ・エラーによってトリガされる
-
fatalError() — 致命的な XML 解析エラーによってトリガされる
-
warning() — パーサ警告の報告によってトリガされる
これらのメソッドは既定では空ですが、カスタム・コンテンツ・ハンドラでオーバーライドできます。期待される引数リストと返り値の詳細は、%XML.SAX.ContentHandlerOpens in a new tab クラスのドキュメントを参照してください。
イベント・マスクの計算
Caché SAX パーサを (%XML.SAX.ParserOpens in a new tab クラス経由で) 呼び出すときに、必要なコールバックを示すマスク引数を指定できます。マスク引数が指定されていない場合、パーサにより、コンテンツ・ハンドラの Mask() メソッドが呼び出されます。このメソッドは、コンテンツ・ハンドラでオーバーライドされたメソッドに対応する複合マスクを表す整数を返します。
例えば、startElement() および endElement() メソッドの新規バージョンを含むカスタム・コンテンツ・ハンドラを作成したとします。この場合、Mask() メソッドは、$$$SAXSTARTELEMENT と $$$SAXENDELEMENT、つまりこれら 2 つのイベントに対応するフラグの合計に等しい数値を返します。解析メソッドにマスク引数を指定しなかった場合、パーサにより、コンテンツ・ハンドラの Mask() メソッドが呼び出されるため、これら 2 つのイベントのみ処理されます。
その他の便利なメソッド
%XML.SAX.ContentHandlerOpens in a new tab クラスには、特定の状況に役立つメソッドが用意されています。
-
LocatePosition() — 解析されたドキュメントの現在位置を表す 2 つの引数を参照として返します。1 つ目の引数は行番号を、2 つ目の引数は行のオフセットを表します。
-
PushHandler() — スタックに新しいコンテンツ・ハンドラをプッシュします。これ以降、このハンドラが処理を完了するまで、SAX からのコールバックはすべて、この新しいコンテンツ・ハンドラに送られます。
このメソッドは、あるタイプのドキュメントを解析しているときに、別の方法で解析する必要のある XML のセグメントに遭遇した場合に使用します。この場合、別の方法で処理する必要のあるセグメントを検出したときには、PushHandler() メソッドを呼び出します。このメソッドは、新しいコンテンツ・ハンドラ・インスタンスを作成します。直前のコンテンツ・ハンドラに戻るために PopHandler() を呼び出すまで、すべてのコールバックはこのコンテンツ・ハンドラに送られます。
-
PopHandler() — スタックに入っている直前のコンテンツ・ハンドラに戻ります。
これらのメソッドは確定されています。オーバーライドできません。
SAX 解析メソッドの引数リスト
ドキュメント・ソースを解析するには、%XML.SAX.ParserOpens in a new tab クラスの ParseFile()、ParseStream()、ParseString()、または ParseURL() メソッドを使用します。どのような場合でも、ソース・ドキュメントは、適格な XML ドキュメント、つまり、XML 構文の基本的な規約に従ったドキュメントである必要があります。以下に、全引数のリストを順番に記載します。
-
pFilename、pStream、pString、または pURL — ドキュメント・ソース。
-
pHandler — コンテンツ・ハンドラ。これは %XML.SAX.ContentHandlerOpens in a new tab クラスのインスタンスです。
-
pResolver — ソースの解析時に使用されるエンティティ・リゾルバ。詳細は、この章で前述した “カスタム・エンティティの解析実行” を参照してください。
-
pFlags — SAX パーサによる検証と処理を制御するフラグ。詳細は、この章で前述した “パーサ・フラグの設定” を参照してください。
-
pMask — XML ソース内の目的の項目を指定するためのマスク。%XML.SAX.ParserOpens in a new tab の解析メソッドに対する既定のマスクは 0 であるため、通常はこの引数を指定する必要はありません。つまり、パーサは、コンテンツ・ハンドラの Mask() メソッドを呼び出します。このメソッドはマスクを計算するために、イベント・ハンドラでカスタマイズされたイベント・コールバックをすべて (コンパイル中に) 検出します。処理されるのはこれらのイベント・コールバックのみです。ただし、マスクを指定する必要がある場合は、この章で前述した “イベント・マスクの指定” を参照してください。
-
pSchemaSpec — ドキュメント・ソースの検証の基準となるスキーマ仕様。この引数は、ネームスペース/URL のペアをコンマで区切って指定したリストを含む文字列です。
"namespace URL,namespace URL"
ここで、namespace はスキーマに使用する XML ネームスペースで、URL はスキーマ・ドキュメントの位置を表す URL です。ネームスペースと URL の値の間は、1 つの空白文字で区切られています。
-
pHttpRequest (ParseURL() メソッドのみ) — %Net.HttpRequestOpens in a new tab のインスタンスとしての、Web サーバへの要求。
%Net.HttpRequestOpens in a new tab の詳細は、"Caché インターネット・ユーティリティの使用法" のドキュメントを参照してください。または、%Net.HttpRequestOpens in a new tab のクラス・ドキュメントを参照してください。
-
pSSLConfiguration — クライアント SSL/TLS 構成の構成名。
この章で後述する、“HTTPS の使用” を参照してください。
ただし、この引数リストは、%XML.TextReaderOpens in a new tab クラスの解析メソッドの引数リストとは多少異なります。例えば、%XML.TextReaderOpens in a new tab には、カスタム・コンテンツ・ハンドラを指定するためのオプションはありません。
SAX ハンドラの例
ファイルに表示される XML 要素すべてのリストが必要であるとします。このリストを作成するには、開始要素をすべてメモする必要があります。そのプロセスは、以下のとおりです。
-
%XML.SAX.ContentHandlerOpens in a new tab から派生した、MyApp.Handler というクラスを生成します。
Class MyApp.Handler Extends %XML.SAX.ContentHandler { }
-
startElement() メソッドを、以下のコンテンツでオーバーライドします。
Class MyApp.MyHandler extends %XML.SAX.ContentHandler { // ... Method startElement(uri as %String, localname as %String, qname as %String, attrs as %List) { //we have found an element write !,"Element: ",localname } }
-
外部ファイルを読み取り、解析する Handler クラスにクラス・メソッドを追加します。
Class MyApp.MyHandler extends %XML.SAX.ContentHandler { // ... ClassMethod ReadFile(file as %String) as %Status { //create an instance of this class set handler=..%New() //parse the given file using this instance set status=##class(%XML.SAX.Parser).ParseFile(file,handler) //quit with status quit status } }
処理を実行するためにアプリケーションで実行されるため、これはクラス・メソッドであることに注意してください。このメソッドは、以下を実行します。
-
これは、コンテンツ・ハンドラ・オブジェクトのインスタンスを生成します。
set handler=..%New()
-
これは、%XML.SAX.ParserOpens in a new tab クラスの ParseFile() メソッドを呼び出します。filename で指定されたドキュメントを検証および解析し、コンテンツ・ハンドラ・オブジェクトのさまざまなイベント処理メソッドを実行します。
set status=##class(%XML.SAX.Parser).ParseFile(file,handler)
イベントが発生するたびに、パーサはドキュメント (開始要素、または終了要素など) を解析しますが、パーサはコンテンツ・ハンドラ・オブジェクトで適切なメソッドを実行します。この例でオーバーライドされたメソッドは startElement() のみで、このメソッドはその後、要素名を書き出します。終了要素への到達など、その他のイベントが発生しても、何も起こりません (既定の動作です)。
-
ParseFile() メソッドがファイルの最後に到達したときに戻ります。ハンドラ・オブジェクトは範囲外になり、メモリから自動的に削除されます。
-
-
アプリケーションで適切な位置に到達したら、ReadFile() メソッドを実行し、解析のためにファイルに渡します。
Do ##class(Samples.MyHandler).ReadFile(filename)
filename は、現在読み取られているファイルのパスです。
例えば、このファイルのコンテンツが以下の場合、
<?xml version="1.0" encoding="UTF-8"?>
<Root>
<Person>
<Name>Edwards,Angela U.</Name>
<DOB>1980-04-19</DOB>
<GroupID>K8134</GroupID>
<HomeAddress>
<City>Vail</City>
<Zip>94059</Zip>
</HomeAddress>
<Doctors>
<Doctor>
<Name>Uberoth,Wilma I.</Name>
</Doctor>
<Doctor>
<Name>Wells,George H.</Name>
</Doctor>
</Doctors>
</Person>
</Root>
この例の出力は、以下のようになります。
Element: Root
Element: Person
Element: Name
Element: DOB
Element: GroupID
Element: HomeAddress
Element: City
Element: Zip
Element: Doctors
Element: Doctor
Element: Name
Element: Doctor
Element: Name
HTTPS の使用
%XML.SAX.ParserOpens in a new tab は HTTPS をサポートしています。そのため、このクラスを使用すると、以下を実行できます。
-
(ParseURL() の場合) HTTPS の場所で提供される XML ドキュメントの解析。
-
(すべての解析メソッドの場合) HTTPS の場所でのエンティティの解析。
どのような場合でも、これらの項目が HTTPS の場所で提供されるときには、以下を実行します。
-
管理ポータルを使用して、必要な接続の詳細を格納する SSL/TLS 構成を作成します。詳細は、"Caché セキュリティ管理ガイド" の “Caché での SSL/TLS の使用法” の章を参照してください。
これは、1 回限りの手順です。
-
適用可能な %XML.SAX.ParserOpens in a new tab の解析メソッドを呼び出すときは、pSSLConfiguration 引数を指定します。
既定では、Caché は Xerces エンティティの解析を使用します。%XML.SAX.ParserOpens in a new tab は、以下の場合にのみ、専用のエンティティの解析を使用します。
-
pSSLConfiguration 引数が NULL 以外。
-
プロキシ・サーバが構成されている。
"Caché インターネット・ユーティリティの使用法" の “HTTP 要求の送信” の章にある “プロキシ・サーバの使用法” を参照してください。