Chapter 10 XML Elements and Attributes

Check the required elements and attributes

By default, the next() method does not check for elements and attributes that correspond to attributes marked as required. To have the reader check for the presence of such elements and attributes, set the reader’s CheckRequired attribute to 1 before calling Next(). The default value for this property is 0 for compatibility reasons.

If you set CheckRequired to 1 and call next(), and the imported XML is missing the required elements or attributes, the next() method sets the SC parameter to error code. Such as:

SAMPLES>set next= reader.Next(.object,.status)
 
SAMPLES>w next
0
SAMPLES>d $system.Status.DisplayError(status)
 
ERROR #6318: Property required in XML document: ReqProp
Copy the code

Handle unexpected elements and attributes

Because the source XML document may contain unexpected elements and attributes, % xml.adaptor provides parameters to specify how to react when such a document is imported.

Control how empty elements and attributes are imported

When XML is enabled for objects, you need to specify how null values and empty strings are projected onto XML

One option is to set XMLIGNORENULL to be equal to “Runtime” (case insensitive) in xmL-supporting classes. In this case, when using the % xml. IRIS object, IRIS uses the value of the reader’s IgnoreNull attribute to determine how to handle empty elements or attributes, as shown below:

  • If the reader’sIgnoreNullAttribute is 0(the default), and the element or attribute is empty, the corresponding attribute is set to equal$char(0)
  • If the reader’sIgnoreNullAttribute is 1, and the element or attribute is empty, the corresponding attribute is not set, so equal to “”

The IgnoreNull attribute of the reader is invalid unless XMLIGNORENULL is “Runtime” in an XML-enabled class; Other possible values for XMLIGNORENULL are 0(the default), 1, and “INPUTONLY”;

Example: IgnoreNull is 0(default)

Class EmptyStrings.Import Extends (%Persistent, %XML.Adaptor)
{

Parameter XMLNAME="Test";

///Reader will set IgnoreNull property
Parameter XMLIGNORENULL = "RUNTIME";

Property PropertyA As %String;

Property PropertyB As %String;

Property PropertyC As %String;

Property PropertyD As %String(XMLPROJECTION = "ATTRIBUTE");

Property PropertyE As %String(XMLPROJECTION = "ATTRIBUTE");
}
Copy the code

The following XML files:


      
<Test PropertyD="">
  <PropertyA></PropertyA>
  <PropertyB xsi:nil="true" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
</Test>
Copy the code

If you create an instance of % xml.reader and use it to import this file into the previous class, you get the following result:

  • PropertyAandPropertyDIs equal to the$char(0).
  • All other attributes are equal to “”.

For example, if you wrote a routine to check each property, check its value, and write the output, you might get something like the following:

PropertyA is $char(0)
PropertyB is null
PropertyC is null
PropertyD is $char(0)
PropertyE is null
Copy the code

Example: IgnoreNull is 1

In a variation of the previous example, we set the IgnoreNull property of the reader to 1. In this case, all attributes are equal to “”.

For example, if you wrote a routine to check each property, check its value, and write the output, you might get something like the following:

PropertyA is null
PropertyB is null
PropertyC is null
PropertyD is null
PropertyE is null
Copy the code

Skip earlier parts of the input document

An XML document consists of a set of nodes; The root node is numbered 0, the first element is numbered 1, and so on. You can specify the node to start reading from; This is especially useful for large documents. To do this, set the Node property of the reader. For this value, specify an integer.

Here is an example method:

ClassMethod DemoSkippingAhead(nodenumber As %Integer = 0)
{
    Set cls="GXML.Person"
    Set filename="c:\GXML.Person.xml"
    Set element="Person"

    // Create an instance of % xml.reader
    Set reader = ##class(%XML.Reader%).New() // Start processing filesSet status = reader.OpenFile(filename)
    If $$$ISERR(status) {Do $System.Status.DisplayError(status)}

    // Associate the class name with the XML element name
    Do reader.Correlate(element,cls)
    
    // Skip forward in the file
    Set reader.Node=nodenumber

    // Read objects from an XML file
    While (reader.Next(.object,.status)) {
        Write "Node number "_reader.Node_" contains "_object.Name,! }}Copy the code

This method assumes a specific input file, class name, and element name. By default, this method starts at the beginning of the file. Such as:

GXML>d ##class(Readers.ReadFile).DemoSkippingAhead(a)Node number 3 contains Emerson.Chad I.
Node number 30 contains O'Rielly.Patricia L.
Node number 63 contains Hanson.Brendan T.
Node number 120 contains Orwell.Tara H.
Node number 195 contains Gold.Elvis O.
Node number 234 contains Klein.Brenda U.
Node number 252 contains Yezek.Kristen Q.
Node number 327 contains Quine.Angelo B.
Node number 378 contains Vivaldi.Milhouse J.
Node number 453 contains Yezek.Vincent D.
Node number 471 contains Xander.Juanita D.
Node number 522 contains Winters.Kyra R.
Node number 555 contains Woo.Michelle J.
Node number 636 contains Ihringer.Yan A.
Node number 654 contains West.Hannah N.
Node number 729 contains Xiang.Bob G.
Node number 762 contains Ximines.Howard H.
Node number 789 contains Quixote.Jocelyn P.
Node number 864 contains Hills.Charles E.
Node number 897 contains Evans.Milhouse R.
Copy the code

In contrast, we can skip the following steps:

GXML>d ##class(Readers.ReadFile).DemoSkippingAhead(700).Node number 729 contains Xiang.Bob G.
Node number 762 contains Ximines.Howard H.
Node number 789 contains Quixote.Jocelyn P.
Node number 864 contains Hills.Charles E.
Node number 897 contains Evans.Milhouse R.
Copy the code

Other useful methods

Sometimes, you may need to use the following additional methods of %XMLReader

  • If you need to read from scratchXMLSource document, please useRewind()Methods. This method clears all associations.
  • If you want to explicitly close and clean up the import handler, useClose()Methods. The import handler clears it automatically; This method is included for backward compatibility.

Reader attributes

You can set the following attributes for % xml.reader. To control the overall behavior of a method:

  • useUsePPGHandlerAttribute specifies%XML.ReaderIs using process private global variables when parsing documents. If this property istrue, the instance uses process private global variables. If this property is false, the instance uses memory. If this property is not set (or equal to an empty string), the instance uses the default value, usually memory.

Use the Format attribute to specify the overall Format of the XML document. Specify one of the following values:

  • "Literal", which is used in most of the examples in this chapter.
  • "Encoded"According to theSOAP 1.1The descriptions in the standard are encoded.
  • "Encoded12"According to theSOAP 1.2The descriptions in the standard are encoded.

Note that you can override the Format attribute in the OpenFile(), OpenStream(), OpenString(), and OpenURL() methods.

This property is not valid unless association () and Next() are used.

  • useSummaryProperty forces the reader to import only the summary fields of XML-enabled objects. As described when an object is projected into XML, the summary of the object is defined by itXMLSUMMARYClass parameter, which can be specified as a comma-separated list of properties.
  • useIgnoreSAXWarningsProperty specifies whether the reader should report warnings issued by the SAX parser.

% xml. Reader also provides attributes that can be used to check the document being read:

  • The Document attribute contains the % xml. Document instance, which represents the entire parsed Document being read.

  • The Node attribute is a string representing the current Node of an XML document. Note that 0 represents the document, the parent element of the root element.