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:

  1. create%XML.ReaderThe instance.
  2. This instance can also be specifiedFormatProperty 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().

  1. Please use the%XML.ReaderOne 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.

  1. accessDocumentProperty, which is a DOM. This property is%XML.DocumentInstance, 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.)