Projecting Objects to XML
Projecting Caché Objects to XML
[Back] [Next]
   
Server:docs1
Instance:LATEST
User:UnknownUser
 
-
Go to:
Search:    

This chapter describes how to project Caché objects as XML documents. This chapter includes the following topics:

Class and Property Parameters Discussed in This Chapter
Later chapters discuss the details of controlling the tag names (element and attribute names) and controlling the types.
Projecting a Caché Object to XML
To project an object to XML (alternatively, to define the XML projection of that object), do the following:
  1. Add %XML.Adaptor to the superclass list of the class that defines the object.
    For example:
    Class MyApp.MyClass Extends (%Persistent, %XML.Adaptor)
    {
    //class details
    }
    This step XML-enables the class.
    Alternatively, if the object you are projecting is an instance of a system class, create and use a subclass instead. In the subclass, add %XML.Adaptor to the superclass list.
    Also, Caché provides many specialized XML-enabled classes in its class library. These include classes in the %Zen, %CSP, %Net, %SOAP, and other packages. All these XML-enabled classes inherit from %XML.Adaptor.
  2. If you are creating an XML-enabled subclass of %ListOfDataTypes, %ArrayOfDataTypes, %ListOfObjects, or %ArrayOfObjects, then in the subclass, specify the ELEMENTTYPE class parameter. For example:
    Class MyApp.MyIntegerCollection Extends %ListOfDataTypes
    {
    Parameter ELEMENTTYPE="%Library.Integer";
    
    }
    For ELEMENTTYPE, specify the complete package and class name of the class used in the collection. If you do not specify this parameter, the type is assumed to be a string.
    This step is necessary only if you need a complete XML schema.
  3. Ensure that each property of the XML-enabled class has an XML projection if suitable, as described in the next section.
    In most cases, if the property has an object value, you must XML-enable the class that defines the property. The exceptions are collections and streams when used as properties, as described in the next section.
    No work is necessary for data type classes.
  4. Recompile the changed classes.
Now you can, for example, write the object to an XML document, as described in Using Caché XML Tools.
Exceptions for Objects Used with Web Methods
If you use %ListOfDataTypes, %ListOfObjects, %ArrayOfDataTypes, %ArrayOfObjects as input or output for a web method, it is not necessary to create an XML-enabled subclass. It is necessary to specify ELEMENTTYPE, but you can do this in the method signature.
If you use a stream class as input or output for a web method, it is not necessary to create an XML-enabled subclass.
For further information, see Creating Web Services and Web Clients in Caché.
Ensuring That Properties Have Projections to XML
To ensure that each property of the object has an XML projection:
For information on how Caché XML tools handle property values of different types, see Controlling Transformations of Values,” later in this book. For information on how property types are projected to XML types, see Controlling the Projection to XML Types,” later in this book.
Properties Defined with List of or Array of
For each property that is defined with the syntax Property PropName As List of classname or Property PropName As Array of classname, do the following:
Note:
Caché does not support projecting arrays of streams to XML. If your object has a property that is defined as an array of streams, include XMLPROJECTION="none" for that property.
For example:
Class MyApp.MyXMLObject Extends (%RegisteredObject, %XML.Adaptor)
{
Property MyListOfObjects As list Of MyApp.OtherXMLObject;

Property MyArrayOfObjects As array Of MyApp.OtherXMLObject;

Property MyListOfDT As list Of %String;

Property MyArrayOfDT As array Of %String;

Property MyListOfStreams As list Of %GlobalCharacterStream;

Property MyArrayOfStreams As array Of %GlobalCharacterStream(XMLPROJECTION = "NONE");
}
Properties of Type %ListOfDataTypes or %ArrayOfDataTypes
The XML tools automatically project properties of type %ListOfDataTypes or %ArrayOfDataTypes as containers, as shown later in this book. By default, the container includes string elements.
If you need a correct XML schema, and if it is inappropriate to assume that the elements are strings, then create and use a subclass of the collection class. In the subclass, specify the ELEMENTTYPE class parameter. For example:
Class MyApp.MyIntegerCollection Extends %ListOfDataTypes
{
Parameter ELEMENTTYPE="%Library.Integer";

}
For ELEMENTTYPE, specify the complete package and class name of the class used in the collection.
Properties of Type %ListOfObjects or %ArrayOfObjects
The XML tools automatically project properties of the type %ListOfObjects or %ArrayOfObjects as containers, as shown later in this book. It is necessary, however, to XML-enable the class used in the collection.
For a property of type %ArrayOfObjects, the class used in the collection cannot be a stream class.
If you need a complete XML schema, then you must specify the element type for the collection. To do so, create and use a subclass of the collection class. In the subclass, specify the ELEMENTTYPE class parameter, as shown in the previous section.
Exceptions
If a given property is not projected to XML, there is no need to XML-enable the class to which it refers. The following properties are not projected to XML:
You can project private properties if you set the XMLPROJECTION property parameter to "ELEMENT" or some other appropriate value, as described later in this chapter. The same applies to multidimensional properties. Also, you can project a multidimensional property only if its top node has a value; note that only the top node is included in the projection.
Summary of the Default Projection
The default XML projection is as follows:
Example XML Projection
This section shows an XML-enabled class and its XML projection. Later sections in this chapter show additional example.
Example XML-Enabled Class
The following shows an XML-enabled class that includes the major structural property variations:
Class Basics.BasicDemo Extends (%RegisteredObject, %XML.Adaptor)
{

Parameter XMLTYPENAMESPACE = "mytypes";

Property SimpleProp As %String;

Property ObjProp As SimpleObject;

Property Collection1 As list Of %String;

Property Collection2 As list Of SimpleObject;

Property MultiDimProp As %String [ MultiDimensional ];

Property PrivateProp As %String [ Private ];

}
The XMLTYPENAMESPACE parameter is discussed later; this specifies the target namespace for types defined in this class.
The SimpleObject class is also XML-enabled:
Class Basics.SimpleObject Extends (%RegisteredObject, %XML.Adaptor)
{

Parameter XMLTYPENAMESPACE = "mytypes";

Property MyProp As %String;

Property AnotherProp As %String;

}
Example XML Document
The following shows an XML document generated from an instance of the BasicDemo class:
<?xml version="1.0" encoding="UTF-8"?>
<BasicDemo>
  <SimpleProp>abc</SimpleProp>
  <ObjProp>
    <MyProp>12345</MyProp>
    <AnotherProp>67890</AnotherProp>
  </ObjProp>
  <Collection1>
    <Collection1Item>list item 1</Collection1Item>
    <Collection1Item>list item 2</Collection1Item>
  </Collection1>
  <Collection2>
    <SimpleObject>
      <MyProp>12345</MyProp>
      <AnotherProp>67890</AnotherProp>
    </SimpleObject>
    <SimpleObject>
      <MyProp>12345</MyProp>
      <AnotherProp>67890</AnotherProp>
    </SimpleObject>
  </Collection2>
</BasicDemo>
Example Schema
The following shows the schema for the XML type namespace used in the two sample classes:
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:s="http://www.w3.org/2001/XMLSchema" 
        elementFormDefault="qualified" targetNamespace="mytypes">
  <complexType name="BasicDemo">
    <sequence>
      <element minOccurs="0" name="SimpleProp" type="s:string"/>
      <element minOccurs="0" name="ObjProp" type="s01:SimpleObject" xmlns:s01="mytypes"/>
      <element minOccurs="0" name="Collection1" type="s02:ArrayOfCollection1ItemString" xmlns:s02="mytypes"/>
      <element minOccurs="0" name="Collection2" type="s03:ArrayOfSimpleObjectSimpleObject" xmlns:s03="mytypes"/>
    </sequence>
  </complexType>
  <complexType name="SimpleObject">
    <sequence>
      <element minOccurs="0" name="MyProp" type="s:string"/>
      <element minOccurs="0" name="AnotherProp" type="s:string"/>
    </sequence>
  </complexType>
  <complexType name="ArrayOfCollection1ItemString">
    <sequence>
      <element maxOccurs="unbounded" minOccurs="0" name="Collection1Item" nillable="true" type="s:string"/>
    </sequence>
  </complexType>
  <complexType name="ArrayOfSimpleObjectSimpleObject">
    <sequence>
      <element maxOccurs="unbounded" minOccurs="0" name="SimpleObject" 
               nillable="true" type="s04:SimpleObject" xmlns:s04="mytypes"/>
    </sequence>
  </complexType>
</schema>
Specifying Format Options for the Projected XML Document
There are two basic formats of XML documents, literal and encoded (SOAP-encoded). For examples of these formats, see Introduction to Caché XML Tools in Using Caché XML Tools. You specify one of these formats when you export data from or import data into an XML-enabled class.
When you add %XML.Adaptor to a class and compile it, Caché writes additional code to the generated routines. By default, this additional code supports both formats. If you need only one format, you can suppress the other format and reduce the amount of generated code. To do so, specify the XMLFORMAT parameter for that class. Use one of the following values (not case-sensitive):
Controlling the Form of the Projection for Simple Properties
A simple property is a property whose type is a data type class or whose type is undeclared (any property without a specified type is assumed to be a string).
To control the form of the XML projection for a simple property, set the XMLPROJECTION parameter for that property. Use one of the following values (not case-sensitive):
Effect of XMLPROJECTION on Simple Properties
Value of XMLPROJECTION Effect on Non-collection Properties
"ELEMENT" The property is projected as an element. This is the default for non-collection properties.
"ATTRIBUTE" The property is projected as an attribute.
"XMLATTRIBUTE" The property is projected as an attribute with the prefix xml.
"WRAPPED" The property is projected as an element with a subelement; the name of the subelement is based on the data type of the property.
"CONTENT" The property is projected as the primary content for this class (that is, the contents of the property are written without any enclosing element). In any class, you cannot specify this value for more than one property.
"NONE" The property is not projected to XML.
The XMLPROJECTION parameter also accepts the values "COLLECTION" or "ELEMENTREF", but those values are deprecated and are not documented here; for details, see the class documentation for %XML.PropertyParameters.
Basic XMLPROJECTION Variations
The following class defines simple properties that use all variations of XMLPROJECTION except for "CONTENT":
Class xmlproj.SimpleProps Extends (%RegisteredObject, %XML.Adaptor)
{

Property Simple1 As %String (XMLPROJECTION="attribute");

Property Simple2 As %String (XMLPROJECTION="xmlattribute");

Property Simple3 As %String;

Property Simple4 As %String (XMLPROJECTION="element");

Property Simple5 As %String (XMLPROJECTION="wrapped");

Property Simple6 As %String (XMLPROJECTION="none");

}
The following shows an example of the XML representation of an instance of this class:
<SimpleProps Simple1="The quick" xml:Simple2="brown fox">
  <Simple3>jumps</Simple3>
  <Simple4>over</Simple4>
  <Simple5>
    <string>the lazy</string>
  </Simple5>
</SimpleProps>
Projecting a Property as Content
The "CONTENT" value enables you to project the class as a simple element with some text content and possibly some attributes, but no subelements.
The following shows an example class that uses this value:
Class xmlproj.SimpleContentProp Extends (%RegisteredObject, %XML.Adaptor)
{

Property Simple1 As %String(XMLPROJECTION = "content");

Property Simple2 As %String(XMLPROJECTION = "attribute");

Property Simple3 As %String(XMLPROJECTION = "element");

}
When you export an instance of such a class:
You cannot specify XMLPROJECTION as "CONTENT" for more than one property in any class. Also, you can use this value only for a property that contains simple, literal value, not a collection or other type of object.
Controlling the Form of the Projection for Object-Valued Properties
For each object-valued property, the default XML projection consists of an XML element (to represent the object itself) with subelements or attributes to represent the properties of that object, as controlled by the XML projection options in that object class. For an example, see Example XML Projection,” earlier in this book.
Note:
Later sections discuss the following special object-valued properties: collections, relationships, and streams.
Specifying the Form of the Projection for an Object-Valued Property
To control how a object property is projected, set the XMLPROJECTION parameter for that property, as follows:
Effect of XMLPROJECTION on Object Properties
Value of XMLPROJECTION Effect on Collection Properties
"WRAPPED" The property is projected as an element with subelements. The element corresponds to the object class. Each subelement corresponds to a property of that class. This is the default for object properties (other than streams).
"ELEMENT" Each property of the object class is projected as an element, without being wrapped in a parent element.
"NONE" The property is not projected to XML.
"ATTRIBUTE", "XMLATTRIBUTE", or "CONTENT" Compile-time error.
For example, consider the following class:
Class Basics.ObjectPropsDemo Extends (%RegisteredObject, %XML.Adaptor)
{

Property Object1 As SimpleObject(XMLPROJECTION = "wrapped");

Property Object2 As SimpleObject(XMLPROJECTION = "element");

}
The following shows an example of the XML representation of an instance of this class:
<ObjectPropsDemo>
  <Object1>
    <SimpleObject>
      <MyProp>abcdef</MyProp>
      <AnotherProp>qrstuv</AnotherProp>
    </SimpleObject>
  </Object1>
  <Object2>
    <MyProp>abcdef</MyProp>
    <AnotherProp>qrstuv</AnotherProp>
  </Object2>
</ObjectPropsDemo>
Specifying an XML Summary
You can easily specify which properties of a class to project to XML when that class is used as a property:
For example, consider the following Address class:
Class xmlsummary.Address Extends (%RegisteredObject, %XML.Adaptor)
{

Parameter XMLSUMMARY = "City,ZipCode";

Parameter XMLDEFAULTREFERENCE = "SUMMARY";

Property Street As %String;

Property City As %String;

Property State As %String;

Property ZipCode As %String;

}
The following shows an example of the XML representation of an instance of this class:
<Address>
  <Street>47 Winding Way</Street>
  <City>Middlebrook</City>
  <State>GA</State>
  <ZipCode>50291</ZipCode>
</Address>
Notice that all properties are included.
Now consider another class that uses the Address class as a property:
Class xmlsummary.Person Extends (%RegisteredObject, %XML.Adaptor)
{

Property Name As %String;

Property Address as Address;

}
The following shows an example of the XML representation of an instance of this class:
<Person>
  <Name>Penelope Farnsworth</Name>
  <Address>
    <City>Middlebrook</City>
    <ZipCode>50291</ZipCode>
  </Address>
</Person>
Here, because the Address class is a property of this class, the XMLSUMMARY and XMLDEFAULTREFERENCE parameters are used, and only the class properties listed in XMLSUMMARY are used in the projection.
You can use the "COMPLETE" option to force an override. For example, the following class also uses the Address class as a property but specifies XMLREFERENCE as "COMPLETE":
Class xmlsummary.Employee Extends (%RegisteredObject, %XML.Adaptor)
{

Property Name As %String;

Property Address As Address(XMLREFERENCE = "COMPLETE");

}
The following shows an example of the XML representation of an instance of this class:
<Employee>
  <Name>Malcom Winters</Name>
  <Address>
    <Street>770 Enders Lane</Street>
    <City>Middlebrook</City>
    <State>GA</State>
    <ZipCode>50293</ZipCode>
  </Address>
</Employee>
All the properties that have XML projections are included; in this case, this means all properties are included.
Projecting Only Object Identifiers
Instead of projecting an object-valued property as shown earlier in this section, you can project only an identifier for the object. To do so, use one of the following values for the XMLDEFAULTREFERENCE class parameter or the XMLREFERENCE property parameter:
Note:
For the property parameter XMLREFERENCE, you can use the "ID", "OID", and "GUID" options only if the value is a persistent object. You receive compile-time errors otherwise.
Similarly, if you set the class parameter XMLDEFAULTREFERENCE to "ID", "OID", or "GUID", and if the class has properties whose values are non-persistent objects, you must explicitly set the property parameter XMLREFERENCE to "COMPLETE"" or "SUMMARY" for those properties.
Controlling the Form of the Projection for Collection Properties
To control the form of the XML projection for a collection property, set the XMLPROJECTION parameter for that property, as follows:
Effect of XMLPROJECTION on Collection Properties
Value of XMLPROJECTION Effect on Collection Properties
"WRAPPED" The property is projected as an element with subelements; each subelement corresponds to an item of the collection. This is the default for collection properties.
"ELEMENT" Each item in the collection is projected as an element, without being wrapped in the parent property.
"NONE" The property is not projected to XML.
"ATTRIBUTE", "XMLATTRIBUTE", or "CONTENT" Compile-time error.
The following sections show examples with properties that are lists or arrays of data types. For collections of objects, the projected elements can have further structure, recursively, depending on the XML projections of those objects.
Specifying the Form of the Projection for List Properties
The following class defines collection properties that use the "WRAPPED" and "ELEMENT" values:
Class xmlproj.DataTypeColls Extends (%RegisteredObject, %XML.Adaptor)
{

Property Collection1 As list Of %String;

Property Collection2 As list Of %String (XMLPROJECTION="wrapped");

Property Collection3 As list Of %String (XMLPROJECTION="element");

}
The following shows an example of the XML representation of an instance of this class:
<?xml version="1.0" encoding="UTF-8"?>
<DataTypeColls>
  <Collection1>
    <Collection1Item>list item 1</Collection1Item>
    <Collection1Item>list item 2</Collection1Item>
  </Collection1>
  <Collection2>
    <Collection2Item>list item 1</Collection2Item>
    <Collection2Item>list item 2</Collection2Item>
  </Collection2>
  <Collection3>list item 1</Collection3>
  <Collection3>list item 2</Collection3>
</DataTypeColls>
For the Collection3 property, which uses "ELEMENT", the XML projection disregards the list nature of the property and instead treats each list item as a separate property of the class.
Specifying the Form of the Projection for Array Properties
For an array, each array item has both a value and a key, and both of these pieces of information must be represented in XML. The key is always projected as an XML attribute within the element. Consider the following class:
Class xmlproj.DataTypeArray Extends (%RegisteredObject, %XML.Adaptor)
{

Property ArrayProp As array Of %String;

}
The following shows an example of the default XML representation of an instance of this class:
<?xml version="1.0" encoding="UTF-8"?>
<DataTypeArray>
  <ArrayProp>
    <ArrayPropItem ArrayPropKey="1">apples</ArrayPropItem>
    <ArrayPropItem ArrayPropKey="2">bananas</ArrayPropItem>
    <ArrayPropItem ArrayPropKey="3">chocolate</ArrayPropItem>
  </ArrayProp>
</DataTypeArray>
If you specify XMLPROJECTION as "ELEMENT", the XML projection is as follows instead:
<?xml version="1.0" encoding="UTF-8"?>
<DataTypeArray>
  <ArrayProp ArrayPropKey="1">apples</ArrayProp>
  <ArrayProp ArrayPropKey="2">bananas</ArrayProp>
  <ArrayProp ArrayPropKey="3">chocolate</ArrayProp>
</DataTypeArray>
Controlling the Form of the Projection for Relationships
Relationships are projected to XML in the same way as other properties, depending on the nature of the collection used in them:
At any given time, only one side of the relationship can be projected, because otherwise there would be an infinite loop. To reverse the way in which the projection is done, use the XMLPROJECTION property parameter.
This principle is best explained by examples.
The Default Projection for Relationships
First, consider the following pair of classes:
The class Parent is the parent of the class Child.
The class Parent has two properties (ParentPropA and ParentPropB) in addition to the relationship property (Children).
Similarly, the class Child has two properties (ChildPropA and ChildPropB) in addition to the relationship property (MyParent).
When you project these classes to XML, you get the following results by default:
The same is true for one-to-many relationships. Specifically, the object on the “one” side includes a projection for the relationship property. The object on the “many” side does not include a projection for the relationship property.
Projecting the Other Side of the Relationship Instead
By specifying the XMLPROJECTION parameter in the relationship properties of both classes, you can project the other side of the relationship instead. The following class is a variation of the class used in the default example.
Class Relationships2.Parent Extends (%Persistent, %XML.Adaptor)
{

Property ParentPropA As %String;

Property ParentPropB As %String;

Relationship Children As Child(XMLPROJECTION = "NONE") [ Cardinality = children, Inverse = MyParent ];

}
Similarly, the Child class is as follows:
Class Relationships2.Child Extends (%Persistent, %XML.Adaptor)
{

Property ChildPropA As %String;

Property ChildPropB As %String;

Relationship MyParent As Parent (XMLPROJECTION="element") [ Cardinality = parent, Inverse = Children ];

}
When you project these classes to XML, you get the following results:
Controlling the Form of the Projection of a Stream Property
For stream properties, the options for the XMLPROJECTION are as follows:
Effect of XMLPROJECTION on Stream Properties
Value of XMLPROJECTION Effect on Stream Properties
"ELEMENT" The stream contents are contained in an element.
"WRAPPED" Treated in the same way as "ELEMENT".
"NONE" The property is not projected to XML.
"ATTRIBUTE", "XMLATTRIBUTE", or "CONTENT" Compile-time error.
This section shows examples of how streams are projected.
For example, consider the following class:
Class Basics.StreamPropDemo Extends (%Persistent, %XML.Adaptor)
{

Property BinStream As %Library.GlobalBinaryStream;

Property CharStream As %Library.GlobalCharacterStream;

}
The following shows an example of the XML representation of an instance of this class:
<StreamPropDemo>
  <BinStream>/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEP
ERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4e
...
VcE/wkZ5wGJBH/joP50UVfQkqaS5dbi34EZtpJgPRlUkf1H402Fy9oIWHHlPj2K/Nn9cfhRRSGip
ZHzbmEPnEwZGGePu5/nj8qNJcpcrG4DxSuEkToDnPPtRRUyKGhPsuqlAxbypAhJ43A/y44q5HbNM
vmx3U9vuJDLG+ASCQW+pxRRSKP/Z</BinStream>
  <CharStream><![CDATA[This is a sample file.
This is line 2.
This is line 3.
This is line 4.]]></CharStream>
</StreamPropDemo>
Controlling the Availability of Projected Properties
You can specify whether each projected property is used by import, export, or both. To do this, you set the XMLIO parameter, which controls how the export and import methods of %XML.Writer and %XML.Reader classes handle a property. This parameter can take one of the following values (not case-sensitive):
This parameter has no effect on a property that is not projected to XML.
Disabling the Projection
If a class is XML-enabled and you want to prevent the class from being projected (perhaps during testing for some reason), you can set the class parameter XMLENABLED to 0. The default is 1.
If you use XMLENABLED to prevent a class from being projected, this class cannot be used as a property by any class that is projected to XML. Setting XMLENABLED to 0 is the same as removing %XML.Adaptor from the superclass list.
Methods in %XML.Adaptor
The methods in %XML.Adaptor are deprecated and are mostly not documented. You should instead use the more robust classes %XML.Writer and %XML.Schema, which provide greater support for namespaces. For information, see Using Caché XML Tools.