Chapter 13 represents an XML document as a DOM
The % xml. Document and % xml. Node classes make it possible to represent any XML Document as a DOM(Document Object Model). This object can then be navigated and modified. You can also create a new DOM and add it to it.
Note: The XML declaration of any XML document used should indicate the character encoding of the document, and the document should be encoded as declared. If character encodings are not declared, InterSystems IRIS will use the default values described in “Input and Output Character encodings” earlier in this book. If these defaults are incorrect, modify the XML declaration so that it specifies the actual character set to use.
Open the XML document as a DOM
To open an existing XML document to use as the DOM, do the following:
- create
%XML.Reader
The instance. - This instance can also be specified
Format
Property to specify the format of the file to import.
By default, IRIS assumes that XML files are in literal format. If the file is SOAP encoded, you must specify this so that the file can be read correctly.
This attribute is invalid except for Correlate() and Next().
- Please use the
%XML.Reader
One of the following methods.
OpenFile()
– Open a file.OpenStream()
– Open a stream.OpenString()
– Open the string.OpenURL()
– Open the URL.
In each case, you have the option to specify a second parameter to the method to override the value of the Format attribute.
- access
Document
Property, which is a DOM. This property is%XML.Document
Instance, which provides methods you can use to find information about the entire document. For example,CountNamespace()
Returns the total number of namespaces used by the DOM.
Or, if the stream contains XML documents, call the GetDocumentFromStream() method of % xml.document. Returns an instance of % xml.document.
Example 1: Convert a file to DOM
For example, the following method reads an XML file and represents an instance of the Document’s return % xml.document:
ClassMethod GetXMLDocFromFile(file) As %XML.Document
{
s reader = ##class(%XML.Reader%).New(a)s status = reader.OpenFile(file)
if $$$ISERR(status) {d $System.Status.DisplayError(status) q $$$NULLOREF}
s document = reader.Document
q document
}
Copy the code
Example 2: Convert an object to DOM
The following methods take OREF and return an instance of % xml.document in the representation object. This method assumes that OREF is an instance of an XML-enabled class:
ClassMethod GetXMLDoc(object) As %XML.Document
{
// Make sure this is an instance of an XML-enabled class
if '$IsObject(object){w "parameter not object" q $$$NULLOREF} s className = $className (object) s isxml = $CLASSMETHOD(classname,"%Extends","%XML.Adaptor") if 'isxml {
w "Parameter is not an instance of an XML-enabled class"
q $$$NULLOREF
}
// Step 1- Write the object as XML to the stream
s writer = ##class(%XML.Writer%).New(a)s stream = # #class(%GlobalCharacterStream%).New(a)s status = writer.OutputToStream(stream)
if $$$ISERR(status) {d $System.Status.DisplayError(status) q $$$NULLOREF}
s status = writer.RootObject(object)
if $$$ISERR(status) {d $System.Status.DisplayError(status) q $$$NULLOREF}
// Step 2- Extract % xml.document from the stream
s status = ##class(%XML.Document).GetDocumentFromStream(stream.document)
if $$$ISERR(status) {d $System.Status.DisplayError(status) q $$$NULLOREF}
quit document
}
Copy the code
Gets the DOM namespace
When IRIS reads an XML document and creates a DOM, it identifies all namespaces used in the document and assigns an index number to each.
The % xml.document instance provides the following methods that you can use to find information about namespaces in a Document:
CountNamespace()
Returns the number of namespaces in the document.
FindNamespace()
Returns the index corresponding to the given namespace.
GetNamespace()
Returns the XML namespace URI for the given index.
The following example method displays a report that shows the namespaces used in the document:
ClassMethod ShowNamespaces(doc As %XML.Document)
{ s count = doc.CountNamespace() w ! ."Number of namespaces in document:"_count
for i = 1 : 1: count { w ! ."Namespace "_i_" is "_doc.GetNamespace(i)
}
}
Copy the code
Navigate the nodes of the DOM
To access the nodes of a document, two different techniques can be used:
-
Use the GetNode() method of the % xml.document instance. This method accepts an integer indicating the node number starting with 1.
-
Call the GetDocumentElement() method of the % xml.document instance.
This method returns an instance of % xml.node, providing properties and methods for accessing information about the root Node and moving to other nodes. The following sections provide more information about using % xml.node.
Move to a child node or sibling node
To move to a child or sibling, use the following method for the % xml.node instance. :
-
MoveToFirstChild()
-
MoveToLastChild()
-
MoveToNextSibling()
-
MoveToPreviousSibling()
Each of these methods moves to another node (as shown in the method name). If so, the method returns TRUE. If not, return False with the same focus as before the method was called.
Each of these methods takes an optional parameter, skipWhitespace. If this parameter is true, the method ignores any whitespace. The default SkipWhitespace value is false.
Move to the parent node
To move to the parent of the current Node, use the MoveToParent() method of the % xml.node instance.
This method takes an optional parameter, restrictDocumentNode. If this parameter is true, the method does not move to the document node (root). The default value for restrictDocumentNode is False.
Move to a specific node
To move to a specific Node, set the NodeId attribute of the % xml. Node instance. Such as:
set saveNode = node.NodeId
/ /... lots of processing
/ /...
// restore position
set node.NodeId=saveNode
Copy the code
Using the ID attribute
In some cases, XML documents may include an attribute called ID that identifies different nodes in the document. Such as:
<? xml version="1.0"? > <team> <member id="alpha">Jack O'Neill</member>
<member id="beta">Samantha Carter</member>
<member id="gamma">Daniel Jackson</member>
</team>
Copy the code
If, as in this example, the document uses an attribute named ID, you can use it to navigate to the node. To do this, use the document’s GetNodeById() method, which returns an instance of % xml.node. (Note that unlike most other navigation methods, this method can come from % xml.document instead of % xml.node.)