Skip to main content

This documentation is for an older version of this product. See the latest version of this content.Opens in a new tab

XData ブロックの定義と使用

XData ブロックは、コンパイル後のクラスで使用するためにクラス定義に含めるデータの名前とユニットで構成されるクラス・メンバです。

基本

XData ブロックは、クラス定義に含めるデータの名前付きユニットです。通常、クラスのメソッドで使用します。一般的に、これは適格な XML ドキュメントですが、JSON や YAML など、他の形式のデータで構成することもできます。

統合開発環境 (IDE) で直接入力することによって XData ブロックを作成できます。

XData ブロックは、名前付きクラス・メンバ です (プロパティ、メソッドなどと同様)。使用できる XData ブロック・キーワードは以下のとおりです。

  • SchemaSpec — オプションで、XData を検証できる XML スキーマを指定します。

  • XMLNamespace — オプションで、XData ブロックが属する XML ネームスペースを指定します。また、当然ながら、XData ブロック自体の中にもネームスペース宣言を含めることができます。

  • MimeType — XData ブロックのコンテンツの MIME タイプ (正式には、インターネット・メディア・タイプOpens in a new tab)。既定値は text/xml です。

XML の格納に使用する場合、XData ブロックは、1 つのルート XML 要素と任意の有効なコンテンツで構成される必要があります。

XData の使用 (XML の例)

プログラム的に任意の XData ブロック内の XML ドキュメントにアクセスするには、%Dictionary.CompiledXDataOpens in a new tab および %Dictionary パッケージのその他のクラスを使用します。

少量のシステム・データを定義する場合は、XData ブロックが役に立ちます。例えば、EPI.AllergySeverity クラスに、プロパティ Code (内部使用) と プロパティ Description (ユーザへの表示用) があるとします。このクラスに、次のように XData ブロックを記述できます。

XData LoadData
{
<table>
 <row>1^Minor</row>
 <row>2^Moderate</row>
 <row>3^Life-threatening</row>
 <row>9^Inactive</row>
 <row>99^Unable to determine</row>
</table>
}

同じクラスに、次のように、この XData ブロックを読み取ってテーブルを生成するクラス・メソッドを記述することもできます。

/// called by EPI.Utils.GenerateData
ClassMethod Setup() As %Status
{
   //first kill extent
   do ..%KillExtent()
   
   // Get a stream of XML from the XData block contained in this class
   Set xdataID="EPI.AllergySeverity||LoadData"
   Set compiledXdata=##class(%Dictionary.CompiledXData).%OpenId(xdataID)
   Set tStream=compiledXdata.Data
   If '$IsObject(tStream) Set tSC=%objlasterror Quit
   
   set status=##class(%XML.TextReader).ParseStream(tStream,.textreader)
   //check status
   if $$$ISERR(status) do $System.Status.DisplayError(status) quit
   
   //iterate through document, node by node
   while textreader.Read()
   {
       if (textreader.NodeType="chars")
       {
           set value=textreader.Value
           set obj=..%New()
           set obj.Code=$Piece(value,"^",1)
           set obj.Description=$Piece(value,"^",2)
           do obj.%Save()
       }
   }
}

これから以下の点がわかります。

  • XData に記述する XML は必要最小限で済みます。つまり、独自の要素や属性を持つ XML 要素としてアレルギー反応程度を記述する代わりに、単なるデータの行を区切り文字列として XData ブロックに記述します。これにより、見やすい形式で設定データを記述できます。

  • EPI.AllergySeverity クラスは、XML 対応ではなく、また XML 対応にする必要もありません。

XData の使用 (JSON の例)

クラスには、次のように JSON コンテンツが含まれる XData ブロックも記述できます。

XData LoadJSONData [MimeType = "application/json"]
{
   {
      "person":"John", 
      "age":30, 
      "car":"Ford"
   }
}

同じクラスに、次のように、この XData ブロックを読み取ってダイナミック・オブジェクトを生成するクラス・メソッドを記述することもできます。

/// Reads a JSON XData block
ClassMethod SetupJSON() As %Status
{
   
   // Get a stream of JSON from the XData block contained in this class
   Set xdataID="Demo.XData||LoadJSONData"
   Set compiledXdata=##class(%Dictionary.CompiledXData).%OpenId(xdataID)
   Set tStream=compiledXdata.Data
   If '$IsObject(tStream) Set tSC=%objlasterror Quit

   // Create a dynamic object from the JSON content and write it as a string
   Set dynObject = {}.%FromJSON(tStream)
   Write dynObject.%ToJSON()

}

XData の使用 (YAML の例)

クラスには、以下の Swagger API 仕様のように、YAML コンテンツが含まれる XData ブロックも記述できます。

XData SampleAPI [mimetype = "application/yaml"] 
{
swagger: "2.0"
info:
  title: Sample API
  description: API description in Markdown.
  version: 1.0.0
host: api.example.com
basePath: /v1
schemes:
  - https
paths:
  /users:
    get:
      summary: Returns a list of users.
      description: Optional extended description in Markdown.
      produces:
        - application/json
      responses:
        200:
          description: OK
}

このクラス・メソッドは XData ブロックを読み取り、そのコンテンツを 1 行ずつ書き込みます。

/// Reads a YAML XData block
ClassMethod SetupYAML() As %Status
{
   
   // Get a stream of YAML from the XData block contained in this class
   Set xdataID="Demo.XData||SampleAPI"
   Set compiledXdata=##class(%Dictionary.CompiledXData).%OpenId(xdataID)
   Set tStream=compiledXdata.Data
   If '$IsObject(tStream) Set tSC=%objlasterror Quit

   // Write the content from the stream, line by line
   While 'tStream.AtEnd { 
      Write tStream.ReadLine(,.sc,.eol) 
      If eol { Write ! } 
   }
}
FeedbackOpens in a new tab