Projecting Objects to XML
Specifying Namespaces for Elements and Attributes
XML elements and attributes can belong to different namespaces, and the XML Schema specification provides for multiple ways of controlling and representing namespace assignment. The %XML.Adaptor
class provides the corresponding support for your XML documents.
This section discusses the following topics:
The XML examples in this chapter are in literal format
|Class and Property Parameters Discussed in This Chapter
This section provides a refresher on XML namespaces and an overview of how InterSystems IRIS objects are assigned to XML namespaces.
The general assumption in this book is that the reader is familiar with XML. It may be worthwhile, however, to review how to determine the namespace, if any, to which an element or attribute is assigned in an XML document.
First, unless the XML document includes a default namespace or a namespace prefix for every element and attribute that it includes, it is necessary to see the corresponding XML schema. Apart from any imported elements or attributes, any element or attribute is one of the following:
Qualified, which means that the element or attribute is in the target namespace of the schema.
Unqualified, which has different meaning for elements and attributes. An unqualified element is in no namespace. An unqualified attribute is in the default namespace, if any, of its containing element.
For each element and attribute that it defines, a schema indicates whether that item is qualified or unqualified. The schema does this by a combination of the following pieces:
The <schema> element can specify the elementFormDefault and attributeFormDefault attributes. This controls the default namespace assignment of any elements and attributes in the schema. The possible values are "qualified" and "unqualified".
These attributes are optional. The default for both of them is "unqualified". That is, by default if a element or attribute is used without a prefix, it is in no namespace.
Second, the definition of an element or attribute can specify the form attribute, which indicates how that item is assigned to a namespace. The possible values are "qualified" and "unqualified".
Consider the following XML document:
<?xml version="1.0" encoding="UTF-8"?>
<ClassA xmlns="mynamespace" xmlns:s01="mynamespace" s01:String1="abcdef">
For simplicity, we assume that the corresponding schema document uses the default values of elementFormDefault and attributeFormDefault, and does not specify the form attribute for any items it defines. Then the items in this document are in namespaces as follows:
The <ClassA> element is in mynamespace, because of two items:
That is the namespace given by the default namespace declaration for this element and its immediate children (xmlns="mynamespace").
The <ClassA> element does not have a namespace prefix that would indicate some other namespace.
The String1 attribute is in mynamespace, because this attribute uses the s01 prefix, and the xmlns:s01 namespace declaration indicates that the s01 refers to the mynamespace namespace.
Because the schema uses the default for attributeFormDefault ("unqualified"), the String1 attribute would be in mynamespace even if it did not use a namespace prefix.
The <ClassB> element is in mynamespace, because this attribute uses the s01 prefix.
The <String3> and <String4> elements are not in any namespace, because of two items:
The element <String2> is the namespace mynamespace, because that is the default namespace specified in its parent element.
In InterSystems IRIS XML support, you specify namespaces on a class-by-class basis. You use the NAMESPACE class parameter to specify the namespace for instances of that class, as well as its immediate child objects. Also, you use the ELEMENTQUALIFIED and ATTRIBUTEQUALIFIED parameters to specify whether properties of its object-valued properties are global (and belong to the same namespace as the parent) or local.
You can also specify ELEMENTQUALIFIED as a property parameter, if needed for unusual scenarios, not discussed in this book.
Particularly with namespaces, it is important to remember that an XML-enabled object is handled differently depending on the context. For example, if you export an Address object at the top level, it is a global element. If you export a Person object that includes a reference to an Address object, then Address is a local element (as are all other properties of Person). Global and local elements are assigned to namespaces differently.
If you import or export an XML-enabled object at the top level, that object becomes a global element and is assigned to a namespace as follows:
For example, consider the following class definition:
Class MyApp.Person Extends (%Persistent, %XML.Adaptor)
Parameter NAMESPACE = "http://www.person.org";
Property Name As %Name [ Required ];
Property DOB As %Date(FORMAT = 5, MAXVAL = "+$h") [ Required ];
If you export or import an object of this class, the projection might look as follows:
This section describes how to specify the namespace for a property that is projected as an element.
If you import or export an XML-enabled object at the top level, any property that is projected as an element becomes a local element by default. There are two possible namespace assignments for these local elements:
Notice that in both cases, the namespace in the child class is ignored.
The default for ELEMENTQUALIFIED
depends on whether the input or output is in literal format
or encoded format. Literal format is the default and the most common.
For literal format, ELEMENTQUALIFIED defaults to 1. For encoded format, ELEMENTQUALIFIED defaults to 0.
You can make a property into a global element and assign it to a namespace. To do so, you set the XMLREF property parameter to 1. The following describes how the corresponding element is assigned to a namespace:
If the REFNAMESPACE property parameter is specified, the element is in that namespace.
Otherwise the element is assigned to a namespace as follows:
If the property is a type and specifies the XSDTYPE class parameter, the element is in the namespace of the parent class.
Otherwise, if the property class defines the NAMESPACE class parameter, the element is in the namespace of the property class.
If the property class does not define either of these class parameters, the element is in no namespace.
The XMLREF property parameter replaces the XMLELEMENTREF property parameter. The XMLELEMENTREF parameter, however, will be supported indefinitely.
This section describes how to specify the namespace for a property that is projected as an attribute. The ATTRIBUTEQUALIFIED parameter specifies whether attributes are qualified by a namespace prefix; the possible values are as follows:
0 (the default), which means that no namespace prefix is included.
1, which means that a namespace prefix is included.
The XMLREF and REFNAMESPACE property parameters are also supported for properties that you project as attributes.
For a property projected as an attribute, if you set the XMLREF property parameter to 1, the corresponding attribute is assigned to a namespace as follows:
If the REFNAMESPACE property parameter is specified, the attribute is in that namespace.
If the property is a type and specifies the XSDTYPE class parameter, the attribute is in the namespace of the parent class.
Otherwise, if the property class defines the NAMESPACE class parameter, the attribute is in the namespace of the property class.
If the property class does not define either of these class parameters, the attribute is in no namespace.
When you generate XML output for an object, the system generates namespace prefixes as needed. The first namespace prefix is s01, the next is s02, and so on. You can specify different prefixes. To do so, set the XMLPREFIX parameter in the class definitions for the XML-enabled objects themselves. This parameter has two effects:
It ensures that the prefix you specify is declared in the XML output. That is, it is declared even if doing so is not necessary.
It uses that prefix rather than the automatically generated prefix that you would otherwise see.
For example, suppose your class definition is as follows:
Class GXML.Person Extends (%Persistent, %XML.Adaptor)
Parameter XMLPREFIX = "p";
Parameter NAMESPACE = "http://www.person.com";
Parameter XMLNAME = "Person";
Property Name As %Name;
For this class, XML output looks like the following:
<?xml version="1.0" encoding="UTF-8"?>
<Person xmlns="http://www.person.com" xmlns:p="http://www.person.com">
To simplify development, debugging, and troubleshooting, InterSystems recommends the following practices:
If you need to specify namespaces, specify NAMESPACE in all your XML-enabled classes. Otherwise, the defaulting rules become complex.
If you need to control whether local elements are qualified, also specify the ELEMENTQUALIFIED parameter in all your XML-enabled classes.
Content Date/Time: 2019-09-18 06:45:48