テキスト・リーダ・メソッドの作成
InterSystems IRIS オブジェクト・クラスとのリレーションシップが必ずしもあるとは限らない任意の XML ドキュメントを読み取るには、%XML.TextReaderOpens in a new tab クラスのメソッドを呼び出します。これにより、ドキュメントを開き、テキスト・リーダ・オブジェクトとして一時的な格納場所にロードします。テキスト・リーダ・オブジェクトには、ナビゲート可能なノードのツリーが含まれ、そのそれぞれにソース・ドキュメントについての情報が含まれています。そのため、記述したメソッドでドキュメントをナビゲートし、ドキュメントに関する情報を検出できます。このオブジェクトのプロパティは、ドキュメント内の現在の場所に応じて、そのドキュメントに関する情報を提示します。検証エラーがある場合、それらのエラーはツリー内のノードとしても表示できます。
全体構造
メソッドは以下の操作の一部またはすべてを実行する必要があります。
-
以下のメソッドのいずれかの最初の引数を使用して、ドキュメント・ソースを指定します。
メソッド |
最初の引数 |
ParseFile() |
完全なパスを含むファイル名ファイル名およびパスは ASCII 文字のみを含む必要があります。 |
ParseStream() |
ストリーム |
ParseString() |
文字列 |
ParseURL() |
URL |
どのような場合でも、ソース・ドキュメントは、適格な XML ドキュメント、つまり、XML 構文の基本的な規約に従ったドキュメントである必要があります。これらのメソッドはそれぞれ、結果が成功だったかどうかを示すステータス ($$$OK または失敗コード) を返します。通常のメカニズムでステータスをテストできます。特に、$System.Status.DisplayError(status) を使用して、エラー・メッセージのテキストを表示できます。
メソッドは $$$OK を返す場合、これらのメソッドのそれぞれに対し、参照 (2 番目の引数) によって、XML ドキュメント内の情報を含むテキスト・リーダ・オブジェクトを返します。
引数をさらに追加すると、エンティティの解析、検証、検出された項目などを制御できます。"解析メソッドの引数リスト" を参照してください。
-
解析メソッドで返されたステータスを確認し、必要に応じて実行を中止します。
解析メソッドが $$$OK を返した場合、テキスト・リーダ・オブジェクトはソース XML ドキュメントに対応しています。このオブジェクトはナビゲートできます。
ドキュメントには多くの場合、"element"、"endelement"、"startprefixmapping" などのノードが含まれています。"ノード・タイプ" に、ノード・タイプの一覧が記載されています。
Important:
どのような検証エラーが発生した場合でも、ドキュメントには "error" ノードまたは "warning" ノードが含まれています。そのようなノードがないか、コードで確認する必要があります。"検証の実行" を参照してください。
-
以下のインスタンス・メソッドのいずれかを使用して、ドキュメントの読み取りを開始します。
-
ドキュメントの最初のノードへ移動するには、Read() を使用します。
-
特定のタイプの最初の要素へ移動するには、ReadStartElement() を使用します。
-
"chars" の最初のノードへ移動するには、MoveToContent() を使用します。
"ドキュメントのナビゲート" を参照してください。
-
このノードで関係するプロパティの値があれば、それを取得します。利用可能なプロパティには、Name、Value、Depth などがあります。"ノード・プロパティ" を参照してください。
-
必要に応じてドキュメントのナビゲートおよびプロパティ値の取得を続けます。
現在のノードが要素の場合、MoveToAttributeIndex() または MoveToAttributeName() メソッドを使用して、要素の属性にフォーカスを移動できます。要素に戻るには、該当する場合は MoveToElement() を使用します。
-
必要に応じて、Rewind() メソッドを使用して、ドキュメントの最初 (最初のノードの前) に戻ります。これは、ソース内を後退できる唯一のメソッドです。
メソッドの実行後、テキスト・リーダは消滅し、関連する一時格納場所もすべてクリーンアップされます。
例 1
ここでは、任意の XML ファイルを読み取り、各ノードのシーケンス番号、タイプ、名前、および値を表示する単純なメソッドを示します。
ClassMethod WriteNodes(myfile As %String)
{
set status=##class(%XML.TextReader).ParseFile(myfile,.textreader)
//check status
if $$$ISERR(status) {do $System.Status.DisplayError(status) quit}
//iterate through document, node by node
while textreader.Read()
{
Write !, "Node ", textreader.seq, " is a(n) "
Write textreader.NodeType," "
If textreader.Name'=""
{
Write "named: ", textreader.Name
}
Else
{
Write "and has no name"
}
Write !, " path: ",textreader.Path
If textreader.Value'=""
{
Write !, " value: ", textreader.Value
}
}
}
この例は、以下を実行します。
-
ParseFile() クラス・メソッドを呼び出します。このメソッドはソース・ファイルを読み取り、テキスト・リーダ・オブジェクトを生成して、変数 doc 内でそのオブジェクトを参照によって返します。
-
ParseFile() が成功した場合、このメソッドは Read() メソッドを実行して、ドキュメント内で次のノードをそれぞれ検索します。
-
各ノードについて、このメソッドは、そのノードのシーケンス番号、ノード・タイプ、ノード名 (存在する場合)、ノード・パス、およびノード値 (存在する場合) が含まれた出力行を記述します。現在のデバイスに出力されます。
以下の例のソース・ドキュメントを考えてみます。
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="mystyles.css"?>
<Root>
<s01:Person xmlns:s01="http://www.root.org">
<Name attr="xyz">Willeke,Clint B.</Name>
<DOB>1925-10-01</DOB>
</s01:Person>
</Root>
このソース・ドキュメントについては、前述のメソッドで以下の出力が生成されます。
Node 1 is a(n) processinginstruction named: xml-stylesheet
path:
value: type="text/css" href="mystyles.css"
Node 2 is a(n) element named: Root
path: /Root
Node 3 is a(n) startprefixmapping named: s01
path: /Root
value: s01 http://www.root.org
Node 4 is a(n) element named: s01:Person
path: /Root/s01:Person
Node 5 is a(n) element named: Name
path: /Root/s01:Person/Name
Node 6 is a(n) chars and has no name
path: /Root/s01:Person/Name
value: Willeke,Clint B.
Node 7 is a(n) endelement named: Name
path: /Root/s01:Person/Name
Node 8 is a(n) element named: DOB
path: /Root/s01:Person/DOB
Node 9 is a(n) chars and has no name
path: /Root/s01:Person/DOB
value: 1925-10-01
Node 10 is a(n) endelement named: DOB
path: /Root/s01:Person/DOB
Node 11 is a(n) endelement named: s01:Person
path: /Root/s01:Person
Node 12 is a(n) endprefixmapping named: s01
path: /Root
value: s01
Node 13 is a(n) endelement named: Root
path: /Root
コメントが無視されていることに注意してください。既定では、%XML.TextReaderOpens in a new tab クラスはコメントを無視します。この変更の詳細は、"解析メソッドの引数リスト" で説明します。
例 2
以下の例では、XML ファイルを読み取り、その中の各要素をリスト表示します。
ClassMethod ShowElements(myfile As %String)
{
set status = ##class(%XML.TextReader).ParseFile(myfile,.textreader)
//check status
if $$$ISERR(status) {do $System.Status.DisplayError(status) quit}
//iterate through document, node by node
while textreader.Read()
{
if (textreader.NodeType = "element")
{
write textreader.Name,!
}
}
}
このメソッドは、NodeType プロパティを使用して、各ノードのタイプをチェックします。そのノードが要素の場合、メソッドはその名前を現在のデバイスに出力します。前述の XML ソース・ドキュメントについては、このメソッドで以下の出力が生成されます。
Root
s01:Person
Name
DOB
ノード・タイプ
ドキュメントのノードはそれぞれ、以下のタイプのいずれかになります。
テキスト・リーダ・ドキュメントのノード・タイプ
タイプ |
説明 |
"attribute" |
XML 属性 |
"chars" |
文字一式 (要素のコンテンツなど)
%XML.TextReaderOpens in a new tab クラスは、他のノード・タイプ ("CDATA"、"EntityReference"、および "EndEntity") を認識しますが、それらを "chars" に自動的に変換します。 |
"comment" |
XML コメント |
"element" |
XML 要素の先頭 |
"endelement" |
XML 要素の終了 |
"endprefixmapping" |
ネームスペースが宣言されているコンテキストの終了 |
"entity" |
XML エンティティ |
"error" |
パーサで検出された検証エラー。"検証の実行" を参照してください。 |
"ignorablewhitespace" |
混在するコンテンツ・モデルのマークアップ間にある空白 |
"processinginstruction" |
XML 処理命令 |
"startprefixmapping" |
ネームスペースを含むまたは含まない可能性がある、XML ネームスペース宣言 |
"warning" |
パーサで検出された検証の警告。"検証の実行" を参照してください。 |
1 つの XML 要素が複数のノードで構成されていることに注意してください。例えば、以下の XML フラグメントを考えてみます。
<Person>
<Name>Willeke,Clint B.</Name>
<DOB>1925-10-01</DOB>
</Person>
SAX パーサは、この XML を以下のノードのセットとして表示します。
ドキュメント・ノードの例
ノード番号 |
ノードのタイプ |
ノード名 (存在する場合) |
ノードの値 (存在する場合) |
1 |
element |
Person |
|
2 |
element |
Name |
|
3 |
chars |
|
Willeke,Clint B. |
4 |
endelement |
Name |
|
5 |
element |
DOB |
|
6 |
chars |
|
1925-10-01 |
7 |
endelement |
DOB |
|
8 |
endelement |
Person |
|
例えば <DOB> 要素は、element ノード、chars ノード、および endelement ノードの 3 つのノードであると見なされることに注意してください。また、この要素のコンテンツは、chars ノードの値としてのみ使用できることにも注意してください。
ノード・プロパティ
%XML.TextReaderOpens in a new tab クラスは XML ドキュメントを解析し、ドキュメントのコンポーネントに対応するノードのセットで構成されるテキスト・リーダ・オブジェクトを作成します。ノード・タイプについては、"ドキュメント・ノード" を参照してください。
別のノードにフォーカスを変更すると、そのテキスト・リーダ・オブジェクトのプロパティが更新され、現在調べているノードについての情報が含められます。ここでは、%XML.TextReaderOpens in a new tab クラスのすべてのプロパティについて説明します。
AttributeCount
現在のノードが要素または属性の場合、このプロパティは、要素の属性の番号を示します。任意の要素内で最初の属性の番号は 1 となります。
その他のタイプのノードでは、このプロパティは 0 になります。
Depth
ドキュメント内での現在のノードの深さを示します。ルート要素の深さは 1 です。ルート要素外の項目の深さは 0 です。属性は、それが属する要素と同じ深さにあることに注意してください。同様に、エラーまたは警告は、そのエラーまたは警告を引き起こした項目と同じ深さになります。
EOF
リーダがソース・ドキュメントの末尾に到達した場合は True、それ以外の場合は False です。
HasAttributes
現在のノードが要素の場合、その要素に属性があれば、このプロパティは True です (属性がなければ False です)。現在のノードが属性の場合、このプロパティは True です。
その他のタイプのノードでは、このプロパティは False になります。
HasValue
現在のノードが値を持つタイプのノードの場合 (その値が Null であっても)、True です。それ以外の場合、このプロパティは False です。具体的には、このプロパティは以下のタイプのノードでは True となります。
-
attribute
-
chars
-
comment
-
entity
-
ignorablewhitespace
-
processinginstruction
-
startprefixmapping
エラーおよび警告のタイプのノードについては、それらのノード・タイプに値があっても、HasValue は False となることに注意してください。
IsEmptyElement
現在のノードが要素であり、空白である場合には True です。それ以外の場合、このプロパティは False です。
LocalName
attribute、element、または endelement のタイプのノードの場合、これは現在の要素または属性の名前からネームスペースの接頭語を除いたものとなります。その他すべてのタイプのノードでは、このプロパティは Null になります。
Name
ノードのタイプに応じた、現在のノードの完全修飾名です。以下のテーブルに詳細を示します。
タイプごとのノード名
ノード・タイプ |
名前と例 |
attribute |
属性の名前。例えば、次のような属性の場合、
groupID="GX078"
Name は次のようになります。
groupID |
element
または
endelement |
要素の名前。例えば、次のような要素の場合、
<s01:Person groupID="GX078">...</s01:Person>
Name は次のようになります。
s01:Person |
entity |
エンティティの名前 |
startprefixmapping
または
endprefixmapping |
接頭語 (存在する場合)。例えば、次のようなネームスペース宣言の場合、
xmlns:s01="http://www.root.org"
Name は次のようになります。
s01
別の例では、次のようなネームスペース宣言の場合、
xmlns="http://www.root.org"
Name は Null になります。 |
processinginstruction |
処理命令のターゲット。例えば、次のような処理命令の場合、
<?xml-stylesheet type="text/css" href="mystyles.css"?>
Name は次のようになります。
xml-stylesheet |
その他すべてのタイプ |
null |
NamespaceUri
attribute、element、または endelement のタイプのノードの場合、これは属性または要素が属するネームスペース (存在する場合) となります。その他すべてのタイプのノードでは、このプロパティは Null になります。
Path
要素のパス。例えば、以下の XML ドキュメントを考えてみます。
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="mystyles.css"?>
<s01:Root xmlns:s01="http://www.root.org" xmlns="www.default.org">
<Person>
<Name>Willeke,Clint B.</Name>
<DOB>1925-10-01</DOB>
<GroupID>U3577</GroupID>
<Address xmlns="www.address.org">
<City>Newton</City>
<Zip>56762</Zip>
</Address>
</Person>
</s01:Root>
City 要素の Path プロパティは /s01:Root/Person/Address/City です。他の要素も同様に処理されます。
ReadState
テキスト・リーダ・オブジェクトの全体の状態を、以下のいずれかで示します。
-
"Initial" は、Read() メソッドがまだ呼び出されていないことを示します。
-
"Interactive" は、Read() メソッドが少なくとも 1 回呼び出されたことを示します。
-
"EndOfFile" は、ファイルの末尾に達したことを示します。
値
ノードのタイプに応じた、現在のノードの値 (存在する場合) です。以下のテーブルに詳細を示します。
タイプごとのノードの値
ノード・タイプ |
値と例 |
attribute |
属性の値例えば、次のような属性の場合、
groupID="GX078"
Value は次のようになります。
GX078 |
chars |
テキスト・ノードのコンテンツ例えば、次のような要素の場合、
<DOB>1925-10-01</DOB>
chars ノードでは、Value は次のようになります。
1925-10-01 |
comment |
コメントのコンテンツ例えば、次のようなコメントの場合、
<!--Comment here-->
Value は次のようになります。
Comment here |
entity |
エンティティの定義 |
error |
エラー・メッセージ。例は、"検証の実行" を参照してください。 |
ignorablewhitespace |
空白のコンテンツ |
processinginstruction |
ターゲット以外の処理命令全体のコンテンツ例えば、次のような処理命令の場合、
<?xml-stylesheet type="text/css" href="mystyles.css"?>
Value は次のようになります。
type="text/css" href="mystyles.css"? |
startprefixmapping |
接頭語の後にスペース文字が 1 つ、その後に URI が続きます。例えば、次のようなネームスペース宣言の場合、
xmlns:s01="http://www.root.org"
Value は次のようになります。
s01 http://www.root.org |
warning |
警告メッセージ。例は、"検証の実行" を参照してください。 |
その他すべてのタイプ (element を含む) |
null |
seq
ドキュメント内のこのノードのシーケンス番号。最初のノードの番号は 1 です。属性には、それが属する要素と同じシーケンス番号が割り当てられていることに注意してください。
解析メソッドの引数リスト
ドキュメント・ソースを解析するには、テキスト・リーダの ParseFile()、ParseStream()、ParseString()、または ParseURL() メソッドを使用します。どのような場合でも、ソース・ドキュメントは、適格な XML ドキュメント、つまり、XML 構文の基本的な規約に従ったドキュメントである必要があります。これらのメソッドでは、最初の 2 つの引数のみが必要となります。参考までに、これらのメソッドの引数を以下に順番に示します。
-
Filename、Stream、String、または URL — ドキュメント・ソース。
ParseFile() では、Filename 引数には ASCII 文字のみを含む必要があります。
-
TextReader — テキスト・リーダ・オブジェクト。メソッドが $$$OK を返す場合に、出力パラメータとして返されます。
-
Resolver — ソースの解析時に使用されるエンティティ・リゾルバ。詳細は、"SAX パーサの使用法のカスタマイズ" の "カスタム・エンティティの解析実行" を参照してください。
-
Flags — SAX パーサによる検証と処理を制御するフラグまたはフラグの組み合わせ。詳細は、"SAX パーサの使用法のカスタマイズ" の "パーサ・フラグの設定" を参照してください。
-
Mask — XML ソース内の目的の項目を指定するためのマスク。詳細は、"SAX パーサの使用法のカスタマイズ" の "イベント・マスクの指定" を参照してください。
Tip:
%XML.TextReaderOpens in a new tab の解析メソッドでは、既定のマスクは $$$SAXCONTENTEVENTS です。これはコメントを無視することに注意してください。可能性のあるタイプのノードをすべて解析するには、この引数に $$$SAXALLEVENTS を使用します。これらのマクロは、%occSAX.inc インクルード・ファイルで定義します。
-
SchemaSpec — ドキュメント・ソースの検証の基準となるスキーマ仕様。この引数は、ネームスペース/URL のペアをコンマで区切って指定したリストを含む文字列です。
"namespace URL,namespace URL"
ここで、namespace はスキーマに使用する XML ネームスペースで、URL はスキーマ・ドキュメントの位置を表す URL です。ネームスペースと URL の値の間は、1 つの空白文字で区切られています。
-
KeepWhiteSpace — 空白を保持するかどうかを指定するオプション。
-
pHttpRequest — (ParseURL() メソッドのみ) %Net.HttpRequestOpens in a new tab のインスタンスとしての、Web サーバへの要求。既定では、システムは %Net.HttpRequestOpens in a new tab の新規インスタンスを作成してそれを使用しますが、代わりに、%Net.HttpRequestOpens in a new tab の別のインスタンスで要求を行うことができます。これは、既存の %Net.HttpRequestOpens in a new tab があり、プロキシおよびその他のプロパティが既に設定されている場合に役立ちます。このオプションは、http のタイプの (file や ftp などではない) URL にのみ適用されます。
%Net.HttpRequestOpens in a new tab の詳細は、"インターネット・ユーティリティの使用法" を参照してください。または、%Net.HttpRequestOpens in a new tab のクラス・ドキュメントを参照してください。
ドキュメントのナビゲート
ドキュメントをナビゲートするには、テキスト・リーダの Read()、ReadStartElement()、MoveToAttributeIndex()、MoveToAttributeName()、MoveToElement()、MoveToContent()、および Rewind() メソッドを使用します。
次のノードへの移動
ドキュメント内の次のノードに進むには、Read() メソッドを使用します。Read() メソッドは、前方のノードが存在しなくなるまで (つまり、ドキュメントの末尾に達するまで)、True の値を返します。前述の例では、このメソッドを以下のようなループで使用しました。
While (textreader.Read()) {
...
}
特定の要素の最初の出現箇所への移動
ドキュメント内の特定の要素の、最初の出現箇所に移動できます。この操作には、ReadStartElement() メソッドを使用します。このメソッドは、要素が検出されなくなるまで True の値を返します。要素が検出されない場合、メソッドはファイルの末尾に達しています。
ReadStartElement() メソッドは、要素名および (オプションで) ネームスペース URI の 2 つの引数をとります。%XML.TextReaderOpens in a new tab クラスはネームスペースの接頭語を処理しないことに注意してください。これにより、ReadStartElement() メソッドでは以下の 2 つの要素の名前が異なると見なします。
<Person>Smith,Ellen W. xmlns="http://www.person.org"</Person>
<s01:Person>Smith,Ellen W. xmlns:s01="http://www.person.org"</s01:Person>
属性への移動
要素に移動すると、その要素に属性がある場合は、以下の 2 つの方法のいずれかでその属性に移動できます。
-
MoveToAttributeIndex() メソッドを使用して、インデックス (要素内の属性の通常の位置) により特定の属性に移動します。このメソッドの引数は、属性のインデックス番号のみです。AttributeCount プロパティを使用して、指定された要素内の属性の数を知ることができます。すべてのプロパティのリストについては、"ノード・プロパティ" を参照してください。
-
MoveToAttributeName() メソッドを使用して、名前により特定の属性に移動します。このメソッドは、属性名および (オプションで) ネームスペース URI の 2 つの引数をとります。%XML.TextReaderOpens in a new tab クラスはネームスペースの接頭語を処理しないことに注意してください。属性に接頭語がある場合、その接頭語は属性名の一部と見なされます。
現在の要素に対する属性を終了したら、Read() などの検索メソッドを実行することで、ドキュメント内の次の要素に移動できます。また、MoveToElement() メソッドを実行して、現在の属性を含む要素に戻ることもできます。
例えば、以下のコードは、インデックス番号によって、現在のノードに対するすべての属性をリストにします。
If (textreader.NodeType = "element") {
// list attributes for this node
For a = 1:1:textreader.AttributeCount {
Do textreader.MoveToAttributeIndex(a)
Write textreader.LocalName," = ",textreader.Value,!
}
}
以下のコードは、現在のノードに対する color 属性の値を検索します。
If (textreader.NodeType = "element") {
// find color attribute for this node
If (textreader.MoveToAttributeName("color")) {
Write "color = ",textreader.Value,!
}
}
コンテンツを含む次のノードへの移動
MoveToContent() メソッドはコンテンツの検出に役立ちます。具体的には以下のとおりです。
巻き戻し
ここで説明するメソッドは、Rewind() メソッドを除き、すべてドキュメント内を前進します。Rewind() メソッドは、ドキュメントの最初に移動し、すべてのプロパティをリセットします。
検証の実行
既定では、ソース・ドキュメントは指定された任意の DTD またはスキーマ・ドキュメントに対して検証されます。ドキュメントに DTD セクションが含まれる場合、そのドキュメントはその DTD に対して検証されます。代わりに、スキーマ・ドキュメントとの照合で検証するには、"解析メソッドの引数リスト" の説明にあるように、ParseFile()、ParseStream()、ParseString()、または ParseURL() の引数リストで目的のスキーマを指定します。
ほとんどのタイプの検証の問題は致命的ではなく、エラーまたは警告のいずれかを発生させます。具体的には、タイプが "error" または "warning" のノードが、ドキュメント・ツリーのエラーが発生した場所に自動的に追加されます。こうしたノードには、他のタイプのノードと同様に移動し、調査できます。
例えば、以下の XML ドキュメントを考えてみます。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Root [
<!ELEMENT Root (Person)>
<!ELEMENT Person (#PCDATA)>
]>
<Root>
<Person>Smith,Joe C.</Person>
</Root>
この場合、検証エラーは予期されません。このトピックで前述したメソッド例 WriteNodes() を思い出してください。そのメソッドを使用してこのドキュメントを読み取る場合、出力は以下のようになります。
Node 1 is a(n) element named: Root
and has no value
Node 2 is a(n) ignorablewhitespace and has no name
with value:
Node 3 is a(n) element named: Person
and has no value
Node 4 is a(n) chars and has no name
with value: Smith,Joe C.
Node 5 is a(n) endelement named: Person
and has no value
Node 6 is a(n) ignorablewhitespace and has no name
with value:
Node 7 is a(n) endelement named: Root
and has no value
一方、ファイルは以下のようになるとします。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Root [
<!ELEMENT Root (Person)>
<!ELEMENT Person (#PCDATA)>
]>
<Root>
<Employee>Smith,Joe C.</Employee>
</Root>
この場合、<Employee> 要素が DTD セクションで宣言されていないので、エラーが予想されます。ここで、メソッド例 WriteNodes() を使用してこのドキュメントを読み取る場合、出力は以下のようになります。
Node 1 is a(n) element named: Root
and has no value
Node 2 is a(n) ignorablewhitespace and has no name
with value:
Node 3 is a(n) error and has no name
with value: Unknown element 'Employee'
while processing c:/TextReader/docwdtd2.txt at line 7 offset 14
Node 4 is a(n) element named: Employee
and has no value
Node 5 is a(n) chars and has no name
with value: Smith,Joe C.
Node 6 is a(n) endelement named: Employee
and has no value
Node 7 is a(n) ignorablewhitespace and has no name
with value:
Node 8 is a(n) error and has no name
with value: Element 'Employee' is not valid for content model: '(Person)'
while processing c:/TextReader/docwdtd2.txt at line 8 offset 8
Node 9 is a(n) endelement named: Root
and has no value
"SAX パーサの使用法のカスタマイズ" の "パーサ・フラグの設定" も参照してください。
例 : ネームスペースのレポート
次のサンプルのメソッドでは、任意の XML ファイルを読み取り、それぞれの要素および属性が属するネームスペースを示します。
ClassMethod ShowNamespacesInFile(filename As %String)
{
Set status = ##class(%XML.TextReader).ParseFile(filename,.textreader)
//check status
If $$$ISERR(status) {do $System.Status.DisplayError(status) quit}
//iterate through document, node by node
While textreader.Read()
{
If (textreader.NodeType = "element")
{
Write !,"The element ",textreader.LocalName
Write " is in the namespace ",textreader.NamespaceUri
}
If (textreader.NodeType = "attribute")
{
Write !,"The attribute ",textreader.LocalName
Write " is in the namespace ",textreader.NamespaceUri
}
}
}
ターミナルで使用すると、このメソッドは以下のような出力を生成します。
The element Person is in the namespace www://www.person.com
The element Name is in the namespace www://www.person.com
次のバリエーションでは、XML 対応オブジェクトを受け取り、それをストリームに書き込んで、そのストリームを使用して同じタイプのレポートを生成しています。
ClassMethod ShowNamespacesInObject(obj)
{
set writer=##class(%XML.Writer).%New()
set str=##class(%GlobalCharacterStream).%New()
set status=writer.OutputToStream(str)
if $$$ISERR(status) {do $System.Status.DisplayError(status) quit ""}
//write to the stream
set status=writer.RootObject(obj)
if $$$ISERR(status) {do $System.Status.DisplayError(status) quit }
Set status = ##class(%XML.TextReader).ParseStream(str,.textreader)
//check status
If $$$ISERR(status) {do $System.Status.DisplayError(status) quit}
//iterate through document, node by node
While textreader.Read()
{
If (textreader.NodeType = "element")
{
Write !,"The element ",textreader.LocalName
Write " is in the namespace ",textreader.NamespaceUri
}
If (textreader.NodeType = "attribute")
{
Write !,"The attribute ",textreader.LocalName
Write " is in the namespace ",textreader.NamespaceUri
}
}
}