Using Caché Objects
Defining and Using XData Blocks
[Home] [Back] [Next]
InterSystems: The power behind what matters   
Class Reference   
Search:    

An XData block is a class member that consists of a name and a unit of data that you include in a class definition for use by the class after compilation. This chapter discusses XData blocks and covers the following topics:

When viewing this book online, use the preface of this book to quickly find related topics.
Basics
An XData block is a named unit of data that you include in a class definition, typically for use by a method in the class. Most frequently, it is a well-formed XML document, but it could consist of other forms of data, such as JSON.
You can create an XData block either by typing it directly in Studio or by using a wizard in Studio.
An XData block is a named class member (like properties, methods, and so on). The available XData block keywords include:
If used to store XML, contents of the XData block must consist of one root XML element, with any valid contents.
Example XData Blocks
Zen uses XData blocks extensively. These XData blocks are all described in Using Zen. The following shows an example:
XData Contents [XMLNamespace="http://www.intersystems.com/zen"]
  {
    <page xmlns="http://www.intersystems.com/zen" title="HelpDesk">
      <html id="title">My Title</html>
      <hgroup>
        <pane paneName="menuPane"/>
        <spacer width="20"/>
        <vgroup width="100%" valign="top">
          <pane paneName="tablePane"/>
          <spacer height="20"/>
          <pane paneName="detailPane"/>
        </vgroup>
      </hgroup>
    </page>
  }
Using XData (XML Example)
To access an XML document in an arbitrary XData block programmatically, you use %Dictionary.CompiledXData and other classes in the %Dictionary package.
An XData block is useful if you want to define a small amount of system data. For example, suppose that the EPI.AllergySeverity class includes the properties Code (for internal use) and Description (for display to the users). This class could include an XData block like the following:
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>
}
The same class could also include a class method that reads this XData block and populates the table, as follows:
/// 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()
           }
   }
}
Notice the following:
Using XData (JSON Example)
A class could also include an XData block containing JSON content, like the following:
XData LoadJSONData [MimeType = "application/json"]
{
   {
      "person":"John", 
      "age":30, 
      "car":"Ford"
   }
}
The same class could also include a class method that reads this XData block and populates a dynamic object, as follows:
/// 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()

}