XML 仮想ドキュメントの DOM スタイル・パスの指定
ここでは、XML 仮想ドキュメントの DOM スタイル・パスを指定する方法を説明します。
これらのパスを使用して、値にアクセスしたり値を設定したりすることができます (例外についても説明します)。
以下の節のほとんどでは、ドキュメントに XML ネームスペースを使用しないことを前提としています。また、最後の節では、XML ネームスペースを使用するドキュメントにこれらのパスを適合させる方法について説明します。
このトピックの例では、"XML 仮想ドキュメントのプロパティ・パスの概要" で示したスキーマが使用されています。
ノードの取得または設定 (基本的なパス)
XML 仮想ドキュメントには、ルート・ノード、要素、テキスト・ノード、コメント、および処理手順の 5 種類のノードがあります。ルート・ノードおよびいずれの要素も、あらゆるタイプの子ノードを持つことができます。その他の種類のノードは、子ノードを持つことができません。また、属性はノードではありません。
以下のテーブルは、XML 仮想ドキュメントのノードの多くを取得または設定するための、基本的な DOM スタイル・パスを示しています。同じタイプまた同じ名前を持つ複数のノードがある場合で、最初のノードを使用したくない場合には、次の節を参照してください。
また、これらのパスは、より複雑な DOM スタイル・パスを作成する場合にも使用します (これについては、後の項で説明します)。
構文 | 参照先 |
---|---|
ルート・ノードの内容。DOM スタイル・パスを使用することが明確である場合 (つまり、スキーマがロードされていない場合) は、"" を使うこともできます。 | |
/root_element_name | 名前が root_element_name であるルート要素の内容。 |
parent/element_name | 指定された親に含まれる、指定された名前 (element_name) を持つ最初の要素の内容。parent は、その親への完全パスです (常に最初にスラッシュが含まれます)。 |
element_reference/text() | element_reference によって示される要素内の最初のテキスト・ノード。 |
element_reference/comment() |
element_reference によって示される要素内の最初のコメント。 返される値には、開始構文 (<!--) または終了構文 (-->) は含まれません。同様に、値の設定時にも、開始構文または終了構文は含めないでください。 InterSystems IRIS® では、XML ファイル内の読み取り時にすべてのコメントが削除されます。存在する可能性のあるコメントは、ユーザが追加したコメントのみです。(それらを追加するには、SetValueAt() をここで示しているようなパスと共に使用します。) |
element_reference/instruction() |
element_reference によって示される要素内の最初の処理手順。 返される値には、開始構文 (<?) または終了構文 (?>) は含まれません。 同様に、値の設定時にも、開始構文または終了構文は含めないでください。 InterSystems IRIS では、XML ファイル内の読み取り時にすべての処理手順が削除されます。存在する可能性のある手順は、ユーザが追加した手順のみです。(それらを追加するには、SetValueAt() をここで示しているようなパスと共に使用します。) |
以下の XML ドキュメントについて考えてみましょう。
<?xml version="1.0" ?>
<Patient xmlns='http://myapp.com'>Sample text node
<!--Sample comment-->
<!--Another comment-->
<Name>Jane Doe</Name>
<Address>
<Street>100 Blank Way</Street>
</Address>
</Patient>
以下のテーブルに、このドキュメントのパスの例をいくつか示します。
パスの例 | 現在のパスの値 |
---|---|
/Patient/Name | Jane Doe |
/Patient/Address |
<Street>100 Blank Way</Street> この場合、参照される要素には (前の例とは対照的に) 子要素が含まれます。DOM スタイル・パスと値の照合時には、空白は無視されることに留意してください。そのため、ドキュメントに改行やインデントが含まれているかどうかに関係なく、ここでの値は指定されたパスと一致します。 |
/Patient/Address/Street | 100 Blank Way |
/Patient/text() | Sample text node |
/Patient/comment() | Sample comment |
ここで、以下のコードのみを含むデータ変換を使用するとします。
set status=target.SetValueAt("892 Broadway","/Patient/Address/Street")
if 'status {do $system.Status.DisplayError(status) quit}
set status=target.SetValueAt("Dr. Badge","/Patient/Doctor/Name")
if 'status {do $system.Status.DisplayError(status) quit}
これらのパスの 1 つは既に存在し、もう 1 つは存在しませんが、両方のパスが有効であることに注意してください。この変換を使用すると、新しいドキュメントは以下のようになります。
<?xml version="1.0" ?>
<Patient xmlns='http://myapp.com'>Sample text node
<!--Sample comment-->
<!--Another comment-->
<Name>Jane Doe</Name>
<Address>892 Broadway</Address>
<Doctor>
<Name>Dr. Badge</Name>
</Doctor>
</Patient>
DOM スタイル・パス設定時の混合コンテンツの使用
要素とテキスト・ノードの両方を含む値へのパスを設定できます。以下に例を示します。
set mixed="SOME TEXT<HOMETOWN>BELMONT</HOMETOWN>"
set status=target.SetValueAt(mixed,"/Patient/Address/Street")
要素とテキスト・ノードの組み合わせは、混合コンテンツと呼ばれます。
DOM スタイル・パスの場合、InterSystems IRIS は、左山括弧 (<) 文字を含む場合に、値が混合コンテンツであると判断します。したがって、DOM スタイル・パスを、左山括弧を含み、かつ有効な XML ではない値に設定する必要がある場合は、文字エンティティ参照 (<) を使用して、エラーを回避します。
次のテーブルは、InterSystems IRIS が各種ノードの混合コンテンツを処理する方法を示しています。
ノードの種類 | InterSystems IRIS がノード値に指定された混合コンテンツを処理する方法 |
---|---|
root | サポート対象外 |
要素またはコメント | InterSystems IRIS は、ノードの現在のコンテンツを特定の混合コンテンツに置き換えます。 |
テキスト・ノードまたは命令 | InterSystems IRIS は、XML の特殊文字をエスケープし、特定のノードの現在のコンテンツを置き換えます。 |
また、属性はノードではありません。
スキーマ依存パスの混合コンテンツの詳細は、"スキーマ依存パス設定時の混合コンテンツの使用" を参照してください。
基本的なパス修飾子の使用
上記の節に示した基本的なパスの最後に、以下の基本的なパス修飾子を追加できます (例外についても説明します)。基本的なパスのいずれかを使用するのと同じ方法で、結果のパスを使用することが可能です。
項目の位置によって項目を参照します。その項目のインスタンスのみがカウントされ、他のタイプの項目は無視されます。
-
値を取得する場合、この構文によって基本的なパスの参照先の項目の n 番目のインスタンス (または空の文字列) が返されます。
-
値を設定する場合、この構文によって基本的なパスの参照先の項目の n 番目のインスタンスが上書きまたは作成されます。
代わりにハイフン (-) を指定すると、最後のインスタンスにアクセスできます。また、角かっこを省略することもできます。
子要素の位置によって子要素を参照します。
代わりにハイフン (-) を指定すると、最後の子にアクセスできます。また、角かっこを省略することもできます。
制限事項:
-
これは、要素を参照する基本パスのみで使用できます。comment() などの関数と併用することはできません。
-
この構文を使用できるのは、値を設定する場合ではなく、値を取得する場合に限られます。
このパス修飾子を他のパス修飾子と組み合わせるには、/[n] 修飾子を最終修飾子として使用します。
項目をノード位置によって示します。
-
値を取得する場合、この構文によって基本パスの参照先の項目の n 番目のインスタンスが返されます。それ以外の場合、このパスは無効となり、エラーが返されます。
-
値を設定する場合、この構文によって基本パスの参照先の項目の n 番目のインスタンスが上書きされます。それ以外の場合、このパスは無効となり、エラーが返されます。
後の節で示す各種のパス修飾子を使用することで、ノードを挿入したり追加したりできます。("パス修飾子のサマリ" も参照してください。)
以下の XML ドキュメントについて考えてみましょう。
<?xml version="1.0" ?>
<Patient xmlns='http://myapp.com'>
<!--Sample comment-->
<!--Another comment-->
Sample text node
<Name>Fred Williams</Name>
<FavoriteColors>
<FavoriteColor>Red</FavoriteColor>
<FavoriteColor>Green</FavoriteColor>
</FavoriteColors>
<Doctor>
<Name>Dr. Arnold</Name>
</Doctor>
</Patient>
以下のテーブルに、このドキュメントのパスの例をいくつか示します。
パスの例 | 現在のパスの値 | メモ |
---|---|---|
/Patient/Name | Fred Williams | |
Fred Williams | このパスは、ドキュメントの最初の要素内の最初の子要素にアクセスします (XML 標準に従って、これがドキュメント内の唯一の要素です)。ここでは、角かっこは省略可能です。 | |
/Patient/FavoriteColors/[1] | Red | ここでは、角かっこは省略可能です。 |
/Patient/FavoriteColors/[2] | Green | ここでは、角かっこは省略可能です。 |
Red | ここでは、角かっこは省略可能です。 | |
Green | ここでは、角かっこは省略可能です。 | |
/Patient/Name[$1] | 空の文字列 | このパスは無効です。<Patient> 内の最初のノードは <Name> 要素ではありません。 |
/Patient/Name[$4] | Fred Williams | |
/Patient/Doctor[$6] | <Name xmlns='http://myapp.com'>Dr. Arnold/Name> | |
/Patient/4 | 空の文字列 | このパスは無効です。<Patient> には 4 つ目の要素がありません。 |
/Patient/comment()[1] | Sample comment | 角かっこが必要です。角かっこを省略すると、このパスは要素名として解釈されるためです。 |
/Patient/comment()[2] | Another comment | 角かっこが必要です。角かっこを省略すると、このパスは要素名として解釈されるためです。 |
/Patient/comment()[$2] | Another comment | 角かっこが必要です。角かっこを省略すると、このパスは要素名として解釈されるためです。 |
/Patient/comment()[-] | Another comment | 角かっこが必要です。角かっこを省略すると、このパスは要素名として解釈されるためです。 |
Full() 関数の使用
要素を参照するパス (基本的なパス、または基本的な修飾子を使用するパスのいずれか) の場合、要素の開始タグおよび終了タグを取得することもできます。そのためには、パスの最後に full() を追加します。
値を設定する場合は、full() 関数が使用できます。DTL 内では、これが [追加] アクションを使用するデータ変換内でしか許可されません。"XML 仮想ドキュメントの割り当てアクション" を参照してください。
以下の XML ドキュメントについて考えてみましょう。
<?xml version="1.0" ?>
<Patient xmlns='http://myapp.com'>
<Name>Jack Brown</Name>
<Address>
<Street>233 Main St</Street>
</Address>
</Patient>
以下のテーブルに、このドキュメントのパスの例をいくつか示します。
パスの例 | 現在のパスの値 |
---|---|
/Patient/Name/full() | <Name xmlns='http://myapp.com'>Jack Brown</Name |
/Patient/Address/full() | |
/Patient/Address/Street/full() |
ルート・ノードの場合、full() 関数は暗黙的に示されます。つまり、以下の 2 つのパスは同等です。
/
/full()
XML 属性の値の取得または設定
属性の値にアクセスするには、以下の DOM スタイル・パスのいずれかを使用します。この節の以降の部分では、element_reference は完全な DOM スタイル・パスです。
構文 | 参照先 |
---|---|
element_reference/@attribute_name | 指定された要素の指定された属性の値。 |
element_reference/@[n] | (値を取得する場合にのみ使用) 指定された要素の (アルファベット順で) n 番目の属性の値。 |
element_reference/@[-] | 指定された要素の最後の属性の値。 |
角かっこを省略することもできます。
例えば、以下の XML ドキュメントについて考えてみましょう。
<?xml version="1.0" ?>
<Patient MRN='000111222' DL='123-45-6789' xmlns='http://myapp.com'>
<Name>Liz Jones</Name>
</Patient>
以下のテーブルに、このドキュメントのパスの例をいくつか示します。
パスの例 | 現在のパスの値 |
---|---|
/Patient/@MRN | 000111222 |
/Patient/@[1] | 000111222 |
/Patient/@2 |
ノードを挿入または追加するためのパス修飾子の使用
ノードを挿入または追加するには、以下のパス修飾子を基本的なパスの最後に追加します。ここに示すパス修飾子は、値を設定する場合にのみ使用してください。
いくつかの追加オプションについて、次の節も参照してください。
指定されたコンテキストにおいて、基本的なパスの参照先の項目のインスタンスを、その項目の n 番目のインスタンスの直前に挿入します。上書きは一切されません。詳細は、以下のテーブルを参照してください。
この項の以降の部分では、n は整数です。
パスの例 | 動作 |
---|---|
/Patient/Episode[~5] |
<Patient> 内に存在する 5 番目の <Episode> 要素の前に、新しい <Episode> 要素を挿入します。 <Patient> に 5 番目の <Episode> 要素が含まれていない場合、InterSystems IRIS によってパディングが行われ、空の <Episode> 要素が作成されるため、挿入された <Episode> が 5 番目の <Episode> になります。新しく挿入される要素はすべて、<Patient> 要素の最後に挿入されます。 パスが中間の存在しない要素を参照する場合、InterSystems IRIS によってそれらが作成されます。 |
/Patient/element(Episode)[~5] |
<Patient> 内に存在する 5 番目の要素の前に、<Episode> 要素を挿入します。 <Patient> に 5 番目のどのタイプの要素も含まれていない場合、このパスは無効になります。element() 関数によって、パディングのために空の要素が生成されることはありません。 |
/Patient/[~5] | 指定できません。挿入する要素の種類に関する情報がないためです。 |
/Patient/element()[~5] |
例えば、以下の XML ドキュメントについて考えてみましょう。
<?xml version="1.0" ?>
<Patient xmlns='http://myapp.com'>
<Name>Betty Hodgkins</Name>
<FavoriteColors>
<FavoriteColor>Purple</FavoriteColor>
</FavoriteColors>
</Patient>
また、データ変換内の以下のコードについても考えてみましょう。
set status=target.SetValueAt("INSERTED COLOR","/Patient/FavoriteColors/FavoriteColor[~4]")
if 'status {do $system.Status.DisplayError(status) quit}
このコード行によって、元のドキュメントが以下のように変換されます。
<?xml version="1.0" ?>
<Patient>
<Name>Betty Hodgkins</Name>
<FavoriteColors>
<FavoriteColor>Purple</FavoriteColor>
<FavoriteColor/>
<FavoriteColor/>
<FavoriteColor>INSERTED COLOR</FavoriteColor>
</FavoriteColors>
</Patient>
もう 1 つの例として、以下の XML ドキュメントについて考えてみましょう。
<Patient xmlns='http://myapp.com'>
<Name>Colin McMasters</Name>
<Address>
<Street>102 Windermere Lane</Street>
</Address>
</Patient>
また、データ変換内の以下のコードについても考えてみましょう。
set status=target.SetValueAt("INSERTED ADDRESS","/Patient/Address/Street[~2]")
if 'status {do $system.Status.DisplayError(status) quit}
このコード行によって、元のドキュメントが以下のように変換されます。
<?xml version="1.0" ?>
<Patient>
<Name>Colin McMasters</Name>
<Address>
<Street>102 Windermere Lane</Street>
<Street>INSERTED ADDRESS</Street>
</Address>
</Patient>
基本的なパスの参照先の項目のインスタンスを、指定された親に含まれる n 番目のノードの直前に挿入します。上書きは一切されません。親に n 個以上のノードが含まれていない場合、このパスは無効になります。
パスの例 | 動作 |
---|---|
/Patient/Episode[~$3] | <Patient> 内に存在する 3 番目のノードの前に、新しい <Episode> 要素を挿入します。親に 3 つ以上のノードが含まれていない場合、このパスは無効になります。 |
/Patient/element(Episode)[~$3] | 指定できません。element() 関数は、要素の位置に対してのみ機能します。 |
/Patient/[~3] | 指定できません。挿入する要素の種類に関する情報がないためです。 |
/Patient/element()[~3] | 複数の理由によって指定できません。上記の項目を参照してください。 |
基本的なパスの参照先の項目のインスタンスを、指定された親の (新しい) 最後のノードとして追加します。上書きは一切されません。
パスの例 | 動作 |
---|---|
/Patient/Episode[~] | <Patient> 内の最後のノードとして、新しい <Episode> 要素を追加します。パスが中間の存在しない要素を参照する場合、InterSystems IRIS によってそれらが作成されます。 |
/Patient/element(Episode)[~] | <Patient> 内の最後のノードとして、<Episode> 要素を追加します。 パスが中間の存在しない要素を参照する場合、このパスは無効になります。 |
/Patient/[~] | 指定できません。追加する要素の種類に関する情報がないためです。 |
/Patient/element()[~] | 指定できません。追加する要素の種類に関する情報がないためです。 |
例えば、以下はデータ変換におけるコード要素の一部を示しています。
set status=target.SetValueAt("orange","/Patient/FavoriteColors/Color[~]")
if 'status {do $system.Status.DisplayError(status) quit}
set status=SetValueAt("pink","/Patient/FavoriteColors/Color[~]")
if 'status {do $system.Status.DisplayError(status) quit}
これによって、2 つの <Color> が新しい子要素として <FavoriteColors> 要素に追加されます。<FavoriteColors> 要素が存在しない場合は、InterSystems IRIS によって作成されます。
"パス修飾子のサマリ" も参照してください。
element() 関数の使用
値を取得または設定する場合は、element() 関数が使用できます。
値を取得する際の element() の使用
構文 | 動作 |
---|---|
element_reference/element() | 指定された要素の最初の子要素を返します。 |
element_reference/element()[n] | 指定された要素の n 番目の子要素を返します。 |
element_reference/element()[-] | 指定された要素の最後の子要素を返します。 |
値を設定する際の element() の使用
構文 | 動作 |
---|---|
parent_element/element(element_name)[~n] | 指定された親の n 番目の子要素の直前に、(element_name 引数で指定された) 要素を挿入します。指定された要素に n 個以上の子要素が含まれていない場合、このパスは無効になります。 |
parent_element/element(element_name)[~] | (element_name 引数で指定された) 要素を、指定された親の最後のノードとして追加します。 |
要素の位置の取得
要素の位置を取得するには、以下の構文を使用します。
構文 | 戻り値 |
---|---|
element_reference/position() | 指定された要素のその親内での要素の位置。 |
element_reference/node-position() | 指定された要素のその親内でのノードの位置。ノードの位置については、要素だけでなく、すべての種類のノードが考慮されます。 |
要素の数の取得
要素の数を取得するには、以下の構文を使用します。
構文 | 戻り値 |
---|---|
|
指定された親内の子要素の数。 |
|
指定された親内の指定された名前を持つ要素の数。(前述の一連のパスとは対照的に) 要素の名前の後にスラッシュがないことに注意してください。 |
|
指定された要素の子ノードの数。 |
|
指定された要素の属性の数。 |
/[*] 以外のすべての場合に、角かっこを省略することができます。InterSystems IRIS では、last() 関数 (count() 関数と同等) および node-last() 関数 (node-count() 関数と同等) もサポートされています。同様の last() 関数が用意されている XPATH に慣れている場合は、last() および node-last() を使用することもできます。
その他のメタデータへのアクセス
XML 仮想ドキュメントのその他のメタデータにアクセスするには、以下の関数を使用します。これらの関数は、パスの最後でのみ使用できます。
対象機能 | 戻り値 |
---|---|
/node-type() | 指定されたノードのタイプ。この関数によって、以下のいずれかの値が返されます。
|
/name() | 指定されたノードの完全名。例 :s01:Patient |
/local-name() | 指定されたノードのローカル名。例 :Patient |
/prefix() | 指定されたノードのネームスペース接頭語。例 :s01 |
/namespace-uri() | 指定されたノードが属しているネームスペースの URI。例 :www.myapp.org |
/prefixes() | 指定された要素の範囲内の、すべてのネームスペース接頭語およびそれぞれに対応する URI。この情報は、カンマ区切りリストとして返されます。各リスト項目は、ネームスペース接頭語と、それに続く等号記号 (=) および URI で構成されます。デフォルトのネームスペース URI は、接頭語なしで最初にリストされます。例 :=http://tempuri.org,s01=http://myns.com |
パス修飾子のサマリ
以下の表に、DOM スタイル・パスのパス修飾子のサマリを示します。
パス修飾子 | Uses | この修飾子が含まれているパスを使用できるメソッド | SetValueAt() と同時に使用する場合、(必要に応じて) パディングを追加するか? |
---|---|---|---|
[n] | n 番目のインスタンスの取得または設定。 | GetValueAt() および SetValueAt() | はい |
/[n] | n 番目の子要素の取得。 | GetValueAt() | なし |
[~n] | n 番目のインスタンスの挿入。 | SetValueAt() | はい |
インスタンスの追加。 | SetValueAt() | いいえ | |
[$n] | n 番目のノード位置でのインスタンスの取得または設定。 | GetValueAt() および SetValueAt() | いいえ |
[~$n] | n 番目のノード位置でのインスタンスの挿入。 | SetValueAt() | いいえ |
ネームスペースを使用するドキュメントのバリエーション
ドキュメントで XML ネームスペースが使用されている場合、ネームスペース内の要素または属性ごとに、そのパスのセクションをネームスペース接頭語とそれに続くコロン (:) を含めるように変更する必要があります。ネームスペース接頭語は、以下のいずれかです。
-
対応する XML スキーマをロード済みの場合は、"XML ネームスペース・トークン" で説明しているとおりに、ネームスペース・トークンを使用します。例 :element_name ではなく、$2:element_name を使用
-
XML スキーマをロードしていない場合、ドキュメントで指定されているとおりのネームスペース接頭語を使用します。例 :s01:Patient
-
ネームスペースを無視するには、ワイルドカード * を使用します。例 :*:Patient
別のオプションとして、ドキュメント内のすべてのネームスペースを無視することもできます。そのためには、パスを / でなく、ワイルドカード *:/ で始めます。
例 :*:/Patient/@MRN
パスの値を設定する場合は、そのパスにワイルドカードを使用することはできません。
DTL の出力ドキュメントは、入力ドキュメントと同じネームスペース接頭語を使用するとは限りません。ネームスペースは同じであっても、接頭語は生成されます。XML 標準によると、接頭語の選択は重要ではありません。
ターミナルでの DOM スタイル・パスのテスト
特に、構文に精通している場合は、仮想ドキュメント・プロパティ・パスをビジネス・プロセスやデータ変換などで使用する前にターミナルでテストできると便利です。DOM スタイル XML パスに対してこれを行うには、ターミナルまたはテスト・コードで次の手順を実行します。
-
適切な XML ドキュメントのテキストを含む文字列を作成します。
-
EnsLib.EDI.XML.DocumentOpens in a new tab の ImportFromString() メソッドを使用してこの文字列から XML 仮想ドキュメントのインスタンスを作成します。
-
このインスタンスの GetValueAt() および SetValueAt() メソッドを使用します。
以下のメソッドがこれらのステップを実行します。
ClassMethod TestDOMPath()
{
set string="<Patient xmlns='http://myapp.com'>"
_"<Name>Jolene Bennett</Name>"
_"<Address><Street>899 Pandora Boulevard</Street></Address>"
_"</Patient>"
set target=##class(EnsLib.EDI.XML.Document).ImportFromString(string,.status)
if 'status {do $system.Status.DisplayError(status) quit}
set pathvalue=target.GetValueAt("/Patient/Name",,.status)
if 'status {do $system.Status.DisplayError(status) quit}
write pathvalue
}
このメソッドの出力を以下に示します。
SAMPLES>d ##class(Demo.CheckPaths).TestDOMPath()
Jolene Bennett
GetValueAt() のその他のオプションは、"pFormat 引数" を参照してください。