Skip to main content

オブジェクトからの XML 出力の記述 : 基礎

ここでは、InterSystems IRIS® データ・プラットフォーム・オブジェクトからの XML 出力、任意のデータの XML 出力、またはその組み合わせを記述する方法についての基本を説明します。詳細については、トピック "オブジェクトからの XML 出力の記述 : 詳細" を参照してください。

"DOM からの XML 出力の記述" では、代替手法についても説明しています。

概要

XML を記述するには、以下のようにします。

  • 特定のオブジェクトの出力が必要な場合は、そのオブジェクトのクラス定義を XML 対応にする必要があります。いくつかの例外はありますが、そのオブジェクトが参照するクラスも、%XML.AdaptorOpens in a new tab の拡張とします。

  • %XML.WriterOpens in a new tab のインスタンスを作成してから、そのインスタンスのメソッドを呼び出します。コードによって目的の XML 出力の全体構造を指定するライター・メソッドを指定します。この全体構造では、文字のエンコード、オブジェクトの記述順序、処理命令も対象とするかどうかなどを指定します。

次のターミナル・セッションは、サンプルの XML 対応クラスを参照する簡単な例を示しています。

GXML>Set p=##class(GXML.Person).%OpenId(1)
 
GXML>Set w=##class(%XML.Writer).%New()
 
GXML>Set w.Indent=1
 
GXML>Set status=w.RootObject(p)
<?xml version="1.0" encoding="UTF-8"?>
<Person GroupID="R9685">
  <Name>Zimmerman,Jeff R.</Name>
  <DOB>1961-10-03</DOB>
  <Address>
    <City>Islip</City>
    <Zip>15020</Zip>
  </Address>
  <Doctors>
    <Doctor>
      <Name>Sorenson,Chad A.</Name>
    </Doctor>
    <Doctor>
      <Name>Sorenson,Chad A.</Name>
    </Doctor>
    <Doctor>
      <Name>Uberoth,Roger C.</Name>
    </Doctor>
  </Doctors>
</Person>

全体構造

コードは、以下の操作の一部またはすべてをこの順序で実行する必要があります。

  1. 無効である可能性のあるオブジェクトを使用する場合は、そのオブジェクトの %ValidateObject() メソッドを呼び出し、返されるステータスをチェックします。オブジェクトが有効ではない場合、XML も有効とはなりません。

    %XML.WriterOpens in a new tab ではエクスポートの前にオブジェクトの検証はしません。これは、オブジェクトの作成完了後にそれが未検証である場合、(例えば、必須プロパティが失われてるために) オブジェクト (XML) が無効となる可能性があることを意味します。

  2. %XML.WriterOpens in a new tab クラスのインスタンスを作成し、オプションでそのプロパティを設定します。

    特に以下のプロパティを設定する必要がある場合があります。

    • Indent — 出力にインデントと行のラッピングを適用するかどうかを制御します。Indent を 1 に設定するとインデントと行のラッピングが適用され、Indent を 0 に設定すると出力は長い単一の行となります。既定値は 0 です。"インデント・オプションに関する詳細" を参照してください。

    • IndentChars — インデントに使用する文字を指定します。既定では、2 つのスペースで構成される文字列です。Indent を 0 に設定すると、このプロパティには何の効果もなくなります。

    • Charset — 使用する文字セットを指定します。"出力の文字セットの指定" を参照してください。

    ドキュメントを読みやすくするために、ここで挙げる例では Indent を 1 に設定します。

    また、"プロローグに影響するプロパティ" および "ライターのその他のプロパティ" も参照してください。

  3. 出力先を指定します。

    既定では、現在のデバイスに出力されます。出力先を指定するには、ドキュメントの出力を開始する前に、以下のメソッドのいずれかを呼び出します。

    • OutputToDevice() — 出力先を現在のデバイスに設定します。

    • OutputToFile() — 出力先を指定されたファイルに設定します。パスの指定は、絶対パスでも相対パスでもかまいません。存在するディレクトリ・パスを指定するようにします。

    • OutputToString() — 出力先を文字列に設定します。その後で、他のメソッドを使用してこの文字列を取得できます。

    • OutputToStream() — 出力先を指定されたストリームに設定します。

  4. ドキュメントを開始します。これには StartDocument() メソッドを使用できます。StartDocument() でドキュメントを開始していない場合は、Write()WriteDocType()RootElement()WriteComment()、および WriteProcessingInstruction() の各メソッドを使用すると、暗黙的にドキュメントを開始できます。

  5. 必要に応じて、ドキュメントのプロローグの行を記述します。使用できるメソッドは以下のとおりです。

  6. 必要に応じて、既定のネームスペースを指定します。XML ネームスペースが定義されていないクラスにはこれが使用されます。"既定のネームスペースの指定" を参照してください。

    必要に応じて、ルート要素にネームスペース宣言を追加します。このためには、ルート要素を開始するにいくつかのユーティリティ・メソッドを呼び出すことができます。"ネームスペース宣言の追加" を参照してください。

  7. ドキュメントのルート要素の記述を開始します。その詳細は、そのルート要素を InterSystems IRIS オブジェクトに対応させるかどうかで異なります。以下の 2 つの可能性があります。

    • ルート要素は InterSystems IRIS オブジェクトに直接対応している可能性があります。多くの場合、これに該当するのは、ある 1 つのオブジェクトのみの出力を生成する場合です。

      この場合は、RootObject() メソッドを使用し、指定の XML 対応オブジェクトをルート要素として記述します。

    • ルート要素を要素セットの単なるラッパにでき、これらの要素は InterSystems IRIS オブジェクトです。

      この場合は、RootElement() メソッドを使用して、指定した名前を持つルートレベル要素を挿入します。

    また、"ルート要素の記述" も参照してください。

  8. RootElement() メソッドを使用した場合は、1 つ以上の要素の出力をルート要素の中に生成するメソッドを呼び出します。ルート要素の中には、自由な順序と論理であらゆる要素を記述できます。個々の要素を記述する方法にはいくつか種類があり、これらを組み合わせることもできます。

    • Object() メソッドを使用して、XML 対応オブジェクトを記述できます。この要素の名前を指定します。または、オブジェクトで定義されている既定の名前を使用することもできます。

    • Element() メソッドを使用すると、要素の開始タグを指定した名前で記述できます。それに続いて、WriteAttribute()WriteChars()WriteCData()、およびその他のメソッドを使用して、要素のコンテンツ、属性、子要素を記述できます。この子要素には、他の Element() または Object() を使用できます。要素の終了を示すには、EndElement() メソッドを使用します。

    • %XML.ElementOpens in a new tab クラスを使用して、要素を手動で構築できます。

    詳細は、"要素の手動作成" を参照してください。

  9. RootElement() メソッドを使用した場合、EndRootElement() メソッドを呼び出します。このメソッドを使用すると、ドキュメントのルート要素が閉じ、インデントを使用している場合は、ドキュメントの構成に応じてインデントが減少します。

  10. StartDocument() メソッドを使用して開始したドキュメントでは、EndDocument() メソッドを呼び出してドキュメントを閉じます。

  11. 出力先を文字列とした場合は、GetXMLString() メソッドを使用するとその文字列を取得できます。

この他にも作成方法は考えられますが、特定の状況でなければ呼び出せないメソッドがある点は注意を要します。具体的には、あるドキュメントの記述を開始すると、そのドキュメントを終了しない限り、他のドキュメントを開始できません。ドキュメントを開始したまま、他のドキュメントを開始しようとすると、ライター・メソッドから次のステータスが返されます。

#6275: Cannot output a new XML document or change %XML.Writer properties 
until the current document is completed.

StartDocument() メソッドは、ドキュメントを明示的に開始します。Write()WriteDocType()RootElement()WriteComment()、および WriteProcessingInstruction() など、他のメソッドはドキュメントを暗黙的に開始します。

Note:

ここで説明したメソッドは、具体的な構成単位を XML ドキュメントに記述できるように設計されていますが、ドキュメントに対するさらに高度な制御が必要なこともあります。%XML.WriterOpens in a new tab クラスには別のメソッドとして Write() があります。このメソッドを使用すると、出力の中のどの位置にでも任意の文字列を記述できます。

また、Reset() メソッドを使用して、ライター・プロパティを再初期化できます。これは、XML ドキュメントを生成し、ライター・インスタンスを新しく作成せずに別の XML ドキュメントを生成しようとする場合に役立ちます。

エラーのチェック

%XML.WriterOpens in a new tab のメソッドのほとんどはステータスを返します。メソッドを実行するたびに返されるステータスを確認し、必要に応じて実行を中止します。

コメント行の挿入

コメント行を挿入するには WriteComment() メソッドを使用します。このメソッドは、ドキュメント内の任意の場所で使用できます。XML ドキュメントの記述を開始していない場合は、このメソッドを実行すると暗黙的にドキュメントが開始されます。

以下の例は、指定された XML 対応オブジェクトの XML 出力を生成します。

ClassMethod Write(obj) As %Status
{
    set writer=##class(%XML.Writer).%New()
    set writer.Indent=1

    //these steps are not really needed because 
    //this is the default destination
    set status=writer.OutputToDevice()
    if $$$ISERR(status) {
        do $System.Status.DisplayError(status) 
        quit $$$ERROR($$$GeneralError, "Output destination not valid")
    }

    set status=writer.RootObject(obj)
    if $$$ISERR(status) {
        do $System.Status.DisplayError(status) 
        quit $$$ERROR($$$GeneralError, "Error writing root object")
    }
        
    quit status
}

この例は OutputToDevice() メソッドを使用して、出力を既定の出力先である現在のデバイスに転送することに注意してください。

このメソッドを以下のように実行するとします。

 set obj=##class(GXML.Person4).%OpenId(1)
 do ##class(MyWriters.BasicWriter).Write(obj)

出力は当然、使用されるクラスに依存しますが、以下のようになる場合があります。

<?xml version="1.0" encoding="UTF-8"?>
<Person4>
  <Name>Tesla,Alexandra L.</Name>
  <DOB>1983-11-16</DOB>
  <GroupID>Y9910</GroupID>
  <Address>
    <City>Albany</City>
    <Zip>24450</Zip>
  </Address>
  <Doctors>
    <Doc>
      <Name>Schulte,Frances T.</Name>
    </Doc>
    <Doc>
      <Name>Smith,Albert M.</Name>
    </Doc>
  </Doctors>
</Person4>

インデント・オプションに関する詳細

ライターの Indent プロパティを使用して、出力結果に追加の改行が含まれるようにして、より読みやすいものにすることができます。このフォーマットに対する正式な仕様はありません。ここでは、Indent が 1 に等しい場合に %XML.WriterOpens in a new tab によって使用されるルールについて説明します。

  • 空白文字のみを含む要素があれば、空の要素に変換されます。

  • 各要素は、別々の行に配置されます。

  • ある要素が、先行する要素の子である場合には、その要素は親要素を基準にしてインデントされます。このインデント設定は、2 つのスペースを既定値とする IndentChars プロパティによって決定されます。

FeedbackOpens in a new tab