XML ツールを使用する場合の検討事項
任意の種類の XML ツールを操作する場合には、以下のように、一般的に検討すべき事項が少なくとも 3 つあります。
入出力の文字エンコード
XML ドキュメントをエクスポートするときには、使用する文字エンコードを指定できます。指定しなかった場合は、エクスポート先に応じて、InterSystems IRIS® データ・プラットフォームによってエンコードが選択されます。
-
出力先がファイルまたはバイナリ・ストリームの場合は、"UTF-8" が既定です。
-
出力先が文字列または文字ストリームの場合は、"UTF-16" が既定です。
InterSystems IRIS によって読み取られた任意の XML ドキュメントでは、ドキュメントの XML 宣言にそのファイルの文字エンコードを明記する必要があり、明記しておけば、ドキュメントは宣言どおりにエンコードされるようになります。以下はその例です。
<?xml version="1.0" encoding="UTF-16"?>
ただし、文字エンコードがドキュメントで宣言されていない場合は、以下のように想定されます。
-
ドキュメントがファイルまたはバイナリ・ストリームの場合は、文字セットが "UTF-8" と想定されます。
-
ドキュメントが文字列または文字ストリームの場合は、文字セットが "UTF-16" と想定されます。
文字セットおよび変換テーブルの詳細は、"変換テーブル" を参照してください。
ドキュメント形式の選択
XML ドキュメントを操作するときには、ドキュメントを InterSystems IRIS のクラスにマップするときに使用する形式を認識しておく必要があります。同様に、XML ドキュメントを作成するときには、ドキュメントを記述するときに使用するドキュメント形式を指定します。XML ドキュメント形式は、以下のとおりです。
-
リテラルとは、ドキュメントがオブジェクト・インスタンスのリテラル・コピーであることを示します。ほとんどの場合、作業対象が SOAP の場合でもリテラル形式を使用します。
別途明記されている場合を除き、このドキュメントに挙げている例ではリテラル形式を使用しています。
-
エンコードとは、SOAP 1.1 規格または SOAP 1.2 規格で説明されている方法でエンコードされていることを示します。これらの規格へのリンクは、"XML 標準" を参照してください。
SOAP 1.1 と SOAP 1.2 では、詳細が少し異なります。
以下のサブセクションに、これらのドキュメント形式の違いを示します。
リテラル形式
以下の例では、XML ドキュメントをリテラル形式で表示します。
<?xml version="1.0" encoding="UTF-8"?>
<Root>
<Person>
<Name>Klingman,Julie G.</Name>
<DOB>1946-07-21</DOB>
<GroupID>W897</GroupID>
<Address>
<City>Bensonhurst</City>
<Zip>60302</Zip>
</Address>
<Doctors>
<DoctorClass>
<Name>Jung,Kirsten K.</Name>
</DoctorClass>
<DoctorClass>
<Name>Xiang,Charles R.</Name>
</DoctorClass>
<DoctorClass>
<Name>Frith,Terry R.</Name>
</DoctorClass>
</Doctors>
</Person>
</Root>
エンコード形式
一方、以下の例では同じデータをエンコード形式で表示します。
<?xml version="1.0" encoding="UTF-8"?>
<Root xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:s="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
...
<DoctorClass id="id2" xsi:type="DoctorClass">
<Name>Jung,Kirsten K.</Name>
</DoctorClass>
...
<DoctorClass id="id3" xsi:type="DoctorClass">
<Name>Quixote,Umberto D.</Name>
</DoctorClass>
...
<DoctorClass id="id8" xsi:type="DoctorClass">
<Name>Chadwick,Mark L.</Name>
</DoctorClass>
...
<Person>
<Name>Klingman,Julie G.</Name>
<DOB>1946-07-21</DOB>
<GroupID>W897</GroupID>
<Address href="#id17" />
<Doctors SOAP-ENC:arrayType="DoctorClass[3]">
<DoctorClass href="#id8" />
<DoctorClass href="#id2" />
<DoctorClass href="#id3" />
</Doctors>
</Person>
<AddressClass id="id17" xsi:type="s_AddressClass">
<City>Bensonhurst</City>
<Zip>60302</Zip>
</AddressClass>
...
</Root>
エンコードされたバージョンでは、以下の違いに注意してください。
-
出力のルート要素に、SOAP エンコードのネームスペースおよび他の標準ネームスペースの宣言が含まれます。
-
このドキュメントには、person、address、および doctor の各要素がすべて同じレベルで含まれます。address 要素および doctor 要素は、この 2 つの要素を参照する person 要素が使用する一意の ID でリスト表示されます。各オブジェクト値プロパティはこの方法で処理されます。
-
最上位レベルの address および doctor 要素の名前は、それらの要素を参照するプロパティと同じ名前ではなく、それぞれのクラスの名前と同じになります。
-
エンコード形式には、属性は含まれません。GroupID プロパティは、Person クラスの属性としてマッピングされます。リテラル形式では、このプロパティは属性として投影されます。ただし、エンコードされたバージョンでは、このプロパティは要素として投影されます。
-
コレクションに対する処理は異なります。例えば、リスト要素には属性 ENC:arrayType があります。
-
各要素は xsi:type 属性の値を持ちます。
SOAP 1.2 の場合、エンコード・バージョンは若干異なります。バージョンを簡単に区別するには、SOAP エンコードのネームスペースの宣言を確認します。
-
SOAP 1.1 の場合、SOAP エンコードのネームスペースは "http://schemas.xmlsoap.org/soap/encoding/" です。
-
SOAP 1.2 の場合、SOAP エンコードのネームスペースは "http://schemas.xmlsoap.org/wsdl/soap12/" です。
パーサの動作
InterSystems IRIS SAX パーサは、InterSystems IRIS により XML ドキュメントが読み取られるたびに使用されるので、その既定の動作を知っておくと役に立ちます。パーサは、以下のようなタスクを行います。
-
XML ドキュメントが適格な文書であるかどうかを検証します。
-
指定されたスキーマまたは DTD を使用して、ドキュメントを検証しようとします。
ここでは、1 つのスキーマには、他のスキーマを参照する <import> 要素および <include> 要素を含めることができる、ということを覚えておくと役に立ちます。以下はその例です。
<xsd:import namespace="target-namespace-of-the-importing-schema" schemaLocation="uri-of-the-schema"/> <xsd:include schemaLocation="uri-of-the-schema"/>
これらの他のスキーマをパーサで使用できる場合以外は、検証は失敗します。特に WSDL ドキュメントの場合は、すべてのスキーマをダウンロードして、修正された場所を使用するように主スキーマを編集することが必要になる場合もあります。
-
すべての外部エンティティを含め、すべてのエンティティを解決しようとします (この作業は他の XML パーサでも行います)。場所によっては、このプロセスには時間がかかる場合もあります。特に、Xerces では一部の URL の解決にネットワーク・アクセサが使用され、実装ではブロックする I/O が使用されます。結果的に、タイムアウトは発生せず、ネットワーク・フェッチがエラー状態になって停止する可能性があります (現実にはまず発生しません)。
また、Xerces では https をサポートしていないので、https に位置するエンティティの解析はできません。
必要に応じて、カスタムのエンティティ・リゾルバを作成したり、エンティティの解析を無効にすることができます。