XmlDoc API: Difference between revisions
mNo edit summary |
|||
Line 15: | Line 15: | ||
</tr> | </tr> | ||
</table> | </table> | ||
The XmlDoc API is based on the use of XML documents. | The <var>XmlDoc</var> API is based on the use of XML documents. | ||
"[[XML processing in Janus SOAP]]" and various XML references | "[[XML processing in Janus SOAP]]" and various XML references | ||
explain that an XML document can contain any type of | explain that an XML document can contain any type of | ||
Line 23: | Line 23: | ||
This character form of an XML document is called the '''serial''' | This character form of an XML document is called the '''serial''' | ||
form. | form. | ||
When operating on an XML document with the XmlDoc API, the serial form is | When operating on an XML document with the <var>XmlDoc</var> API, the serial form is | ||
converted to an | converted to an <var>XmlDoc</var> object. | ||
Only a few categories of operations are needed | Only a few categories of operations are needed | ||
Line 30: | Line 30: | ||
<table class="list"> | <table class="list"> | ||
<tr><th>Receive</th> | <tr><th>Receive</th> | ||
<td>Receive the transmitted text of a document and convert it into an XmlDoc, containing nodes to represent the hierarchy of the XML document.</td></tr> | <td>Receive the transmitted text of a document and convert it into an <var>XmlDoc</var>, containing nodes to represent the hierarchy of the XML document.</td></tr> | ||
<tr><th>Update</th> | <tr><th>Update</th> | ||
<td>Update or create an XmlDoc, by adding, deleting, copying, or replacing nodes.</td></tr> | <td>Update or create an <var>XmlDoc</var>, by adding, deleting, copying, or replacing nodes.</td></tr> | ||
<tr><th>Access</th> | <tr><th>Access</th> | ||
<td>Access nodes in an XmlDoc, and data contained within them.</td></tr> | <td>Access nodes in an <var>XmlDoc</var>, and data contained within them.</td></tr> | ||
<tr><th>Send</th> | <tr><th>Send</th> | ||
<td>Convert an XmlDoc into a textual representation, and transmit it.</td></tr> | <td>Convert an <var>XmlDoc</var> into a textual representation, and transmit it.</td></tr> | ||
<tr><th>Other</th> | <tr><th>Other</th> | ||
<td>There are other operations, such as XmlDoc properties to control certain operations, data structure housekeeping, and debugging facilities.</td></tr> | <td>There are other operations, such as <var>XmlDoc</var> properties to control certain operations, data structure housekeeping, and debugging facilities.</td></tr> | ||
</table> | </table> | ||
Line 45: | Line 45: | ||
It reviews the above categories of operations, showing | It reviews the above categories of operations, showing | ||
how they are accommodated by | how they are accommodated by | ||
the XmlDoc | the <var>XmlDoc</var> | ||
API classes: XmlDoc, XmlNode, and XmlNodelist. | API classes: <var>XmlDoc</var>, <var>XmlNode</var>, and <var>XmlNodelist</var>. | ||
The objects are operated upon by methods | The objects are operated upon by methods | ||
which are members of these classes. | which are members of these classes. | ||
===Typical operations on an XML document=== | ===Typical operations on an XML document=== | ||
This section list the categories of operations on an XML document, and | This section list the categories of operations on an XML document, and | ||
provides the motivation for objects in the XmlDoc | provides the motivation for objects in the <var>XmlDoc</var> | ||
API: | API: <var>XmlDoc</var>s, <var>XmlNode</var>s, and <var>XmlNodelist</var>s. | ||
====Receive==== | ====Receive==== | ||
The process of receiving a document actually consists of two | The process of receiving a document actually consists of two | ||
Line 59: | Line 59: | ||
<li>Receiving the document text | <li>Receiving the document text | ||
using some “transport” mechanism, such as [[Janus Web Server]] (HTTP, as server) | using some “transport” mechanism, such as [[Janus Web Server]] (HTTP, as server) | ||
[[Janus Sockets]] (usually, HTTP, as client), | <var class="product">[[Janus Sockets]]</var> (usually, HTTP, as client), <var class="product">Model 204</var> MQ Series, access from a file, etc. | ||
<li>Converting the XML document (deserialization) into its internal representation (an XmlDoc) | <li>Converting the XML document (deserialization) into its internal representation (an <var>XmlDoc</var>) | ||
so that other operations can be performed on it. | so that other operations can be performed on it. | ||
</ol> | </ol> | ||
If the XML document is received by ''Janus Web Server'', | If the XML document is received by ''Janus Web Server'', | ||
these steps are performed together by the | these steps are performed together by the | ||
[[WebReceive (XmlDoc function)|WebReceive]] function. | <var>[[WebReceive (XmlDoc function)|WebReceive]]</var> function. | ||
For the [[ | For the [[HTTP Helper]], the document text is received by the <var>[[HttpRequest class|HttpRequest]]</var> <var>[[Get (HttpRequest function)|Get]]</var>, | ||
[[Post (HttpRequest function)|Post]] or [[Send (HttpRequest function)|Send]] function, and the | <var>[[Post (HttpRequest function)|Post]]</var> or <var>[[Send (HttpRequest function)|Send]]</var> function, and the | ||
deserialization is done by the HttpResponse [[ParseXml (HttpResponse function)|ParseXml]] function. | deserialization is done by the <var>[[HttpResponse class|HttpResponse]]</var> <var>[[ParseXml (HttpResponse function)|ParseXml]]</var> function. | ||
For other forms of transport, the steps are performed separately: | For other forms of transport, the steps are performed separately: | ||
the text form of the document is received into a | the text form of the document is received into a longstring, and | ||
the | the longstring contents are converted into internal form by the | ||
[[LoadXml (XmlDoc/XmlNode function)|LoadXml]] function. | <var>[[LoadXml (XmlDoc/XmlNode function)|LoadXml]]</var> function. | ||
====Update==== | ====Update==== | ||
You modify an XmlDoc using various [[List of XmlDoc API methods|XmlDoc API methods]]. | You modify an <var>XmlDoc</var> using various [[List of XmlDoc API methods|XmlDoc API methods]]. | ||
If you start with an empty XmlDoc, some methods (the | If you start with an empty <var>XmlDoc</var>, some methods (the | ||
Add* and Insert* methods for various node types) | <var>Add</var>* and <var>Insert</var>* methods for various node types) | ||
allow you to generate an XmlDoc | allow you to generate an <var>XmlDoc</var> "directly", without first | ||
representing it in the serial text form. | representing it in the serial text form. | ||
You can also update an XmlDoc into which you have received a document. | You can also update an <var>XmlDoc</var> into which you have received a document. | ||
====Access==== | ====Access==== | ||
Since an XML document is a hierarchical structure, your application | Since an XML document is a hierarchical structure, your application | ||
Line 95: | Line 95: | ||
XPath can be used for accessing a single node in the document, for | XPath can be used for accessing a single node in the document, for | ||
example, getting an element node's string value using the | example, getting an element node's string value using the | ||
[[Value (XmlDoc/XmlNode property)|Value property]]. | <var>[[Value (XmlDoc/XmlNode property)|Value property]]</var>. | ||
You can also work with lists of selected nodes, represented by | You can also work with lists of selected nodes, represented by <var>XmlNodelist</var>s. | ||
The [[SelectNodes (XmlDoc/XmlNode function)|SelectNodes]] function | The <var>[[SelectNodes (XmlDoc/XmlNode function)|SelectNodes]]</var> function | ||
produces such a list. | produces such a list. | ||
Other XmlNodelist methods also | Other <var>XmlNodelist</var> methods also | ||
work with them, including the [[Item (XmlNodelist function)|Item]] function, which gets a single | work with them, including the <var>[[Item (XmlNodelist function)|Item]]</var> function, which gets a single | ||
XmlNode from an XmlNodelist. | <var>XmlNode</var> from an <var>XmlNodelist</var>. | ||
[[SelectSingleNode (XmlDoc/XmlNode function)|SelectSingleNode]] returns an XmlNode, as do most of the Add*/ | <var>[[SelectSingleNode (XmlDoc/XmlNode function)|SelectSingleNode]]</var> returns an <var>XmlNode</var>, as do most of the <var>Add</var>* and <var>Insert</var>*<var>Before</var> | ||
methods. | methods. | ||
====Send==== | ====Send==== | ||
Line 108: | Line 108: | ||
steps: | steps: | ||
<ol> | <ol> | ||
<li>Converting the XmlDoc into its serial text representation. | <li>Converting the <var>XmlDoc</var> into its serial text representation. | ||
<li>Sending the document text | <li>Sending the document text | ||
using some “transport” mechanism, such as ''Janus Web Server'' (HTTP, as server), | using some “transport” mechanism, such as ''Janus Web Server'' (HTTP, as server), | ||
<var class="product">[[Janus Sockets]]</var> (usually, HTTP, as client), <var class="product">Model 204</var> MQ Series, access from a file, etc. | |||
</ol> | </ol> | ||
If the XML document is sent by ''Janus Web Server'', the steps can be | If the XML document is sent by ''Janus Web Server'', the steps can be | ||
performed together by the | performed together by the | ||
[[WebSend (XmlDoc subroutine)|WebSend]] subroutine. | <var>[[WebSend (XmlDoc subroutine)|WebSend]]</var> subroutine. | ||
For the | For the [[HTTP Helper]], the document is serialized by the <var>[[HttpRequest class|HttpRequest]]</var> <var>[[AddXml (HttpRequest subroutine)|AddXml]]</var> subroutine, | ||
and the document is sent by | and the document is sent by | ||
the HttpRequest Get, Post, or Send function. | the <var>HttpRequest</var> <var>Get</var>, <var>Post</var>, or <var>Send</var> function. | ||
For other forms of transport, the steps are performed separately: | For other forms of transport, the steps are performed separately: | ||
the XmlDoc is converted into external form by the | the <var>XmlDoc</var> is converted into external form by the | ||
[[Serial (XmlDoc/XmlNode function)|Serial]] function | <var>[[Serial (XmlDoc/XmlNode function)|Serial]]</var> function | ||
and the converted result is sent using the appropriate transport. | and the converted result is sent using the appropriate transport. | ||
====Other operations==== | ====Other operations==== | ||
Some other operations the XmlDoc API methods perform include: | Some other operations the <var>XmlDoc</var> API methods perform include: | ||
<ul> | <ul> | ||
<li>Creating and initializing an XmlDoc or XmlNodelist. | <li>Creating and initializing an <var>XmlDoc</var> or <var>XmlNodelist</var>. | ||
<li>Setting or retrieving | <li>Setting or retrieving | ||
some property of an XmlDoc, for example, the URI associated with | some property of an <var>XmlDoc</var>, for example, the URI associated with | ||
a prefix to be used in an XPath expression | a prefix to be used in an XPath expression | ||
(see [[SelectionNamespace (XmlDoc property)|SelectionNamespace]]). | (see <var>[[SelectionNamespace (XmlDoc property)|SelectionNamespace]]</var>). | ||
<li>Displaying a document, or some part of it, usually for debugging purposes | <li>Displaying a document, or some part of it, usually for debugging purposes | ||
(see [[Print (XmlDoc/XmlNode subroutine)|Print]]). | (see <var>[[Print (XmlDoc/XmlNode subroutine)|Print]]</var>). | ||
</ul> | </ul> | ||
===The XmlDoc class=== | ===The XmlDoc class=== | ||
<!-- on XmlDoc class page, #REDIRECT [[XmlDoc API#The XmlDoc class]] --> | <!-- on XmlDoc class page, #REDIRECT [[XmlDoc API#The XmlDoc class]] --> | ||
An | An <b><var>XmlDoc</var></b> object is the internal | ||
representation of an XML document; creating one is usually done | representation of an XML document; creating one is usually done | ||
by invoking the XmlDoc [[New (XmlDoc/XmlNodelist constructor)|New]] constructor, | by invoking the <var>XmlDoc</var> [[New (XmlDoc/XmlNodelist constructor)|New]] constructor, | ||
which returns an XmlDoc instance. | which returns an <var>XmlDoc</var> instance. | ||
An XmlDoc is a tree structure of nodes. | An <var>XmlDoc</var> is a tree structure of nodes. | ||
The types of nodes that an XmlDoc may contain are the following: | The types of nodes that an <var>XmlDoc</var> may contain are the following (which are enumeration return values of the | ||
<var>[[Type (XmlDoc/XmlNode function)|Type]]</var> function): | |||
<dl> | <dl> | ||
<dt>Attribute | <dt><var>Attribute</var> | ||
<dd>This type of node is used to represent an attribute of an XML element. | <dd>This type of node is used to represent an attribute of an XML element. | ||
<dt>Comment | <dt><var>Comment</var> | ||
<dd>This type of node is used to represent a comment | <dd>This type of node is used to represent a comment | ||
(serialized in the form: <!--comment-->) in an XML document. | (serialized in the form: <!--comment-->) in an XML document. | ||
<dt>Root | <dt><var>Root</var> | ||
<dd>This type of node is the root of the XmlDoc tree. | <dd>This type of node is the root of the <var>XmlDoc</var> tree. | ||
It has zero or one Element child nodes and any number of Comment and | It has zero or one Element child nodes and any number of <var>Comment</var> and <var>Pi</var> | ||
child nodes. | child nodes. | ||
Root and Element nodes are the only nodes that can have child nodes. | <var>Root</var> and <var>Element</var> nodes are the only nodes that can have child nodes. | ||
<dt>Element | <dt><var>Element</var> | ||
<dd>This type of node is used to represent an element in an XML document. | <dd>This type of node is used to represent an element in an XML document. | ||
Element and Root node ares the only nodes that can have child nodes. | <var>Element</var> and <var>Root</var> node ares the only nodes that can have child nodes. | ||
<dt> | <dt><var>Pi</var> | ||
<dd>This type of node is used to represent a processing instruction | <dd>This type of node is used to represent a processing instruction | ||
( | (<?target ...?>) in an XML document. | ||
'''Note:''' | '''Note:''' | ||
Although the “XML | Although the “XML | ||
declaration” ( | declaration” (<?xml version=...?>) has the same appearance | ||
as a processing instruction, it is not a | as a processing instruction, it is not a <var>Pi</var>. | ||
Also, note that the values of an XmlDoc's XML declaration can be obtained | Also, note that the values of an <var>XmlDoc</var>'s XML declaration can be obtained | ||
and set with these properties: | and set with these properties: | ||
[[Version (XmlDoc property)|Version]], | <var>[[Version (XmlDoc property)|Version]]</var>, | ||
[[Encoding (XmlDoc property)|Encoding]], and | <var>[[Encoding (XmlDoc property)|Encoding]]</var>, and | ||
[[Standalone (XmlDoc property)|Standalone]]. | <var>[[Standalone (XmlDoc property)|Standalone]]</var>. | ||
<dt>Text | <dt><var>Text</var> | ||
<dd>This type of node is used to represent character content within | <dd>This type of node is used to represent character content within | ||
an XML element. | an XML element. | ||
Note that a Text node will never contain the null string, and that two Text nodes | Note that a Text node will never contain the null string, and that two <var>Text</var> nodes | ||
can be adjacent only if the [[AdjacentText (XmlDoc property)|AdjacentText]] property | can be adjacent only if the <var>[[AdjacentText (XmlDoc property)|AdjacentText]]</var> property | ||
is set to allow it. | is set to allow it. | ||
</dl> | </dl> | ||
The XmlDoc node types listed above correspond almost exactly with the structures | The <var>XmlDoc</var> node types listed above correspond almost exactly with the structures | ||
contained in an XML document (see [[XML processing in Janus SOAP#XML|XML]] and [[XML processing in Janus SOAP#XML example|XML example]]). | contained in an XML document (see [[XML processing in Janus SOAP#XML|XML]] and [[XML processing in Janus SOAP#XML example|XML example]]). | ||
The Root node is always present and | The <var>Root</var> node is always present and | ||
corresponds to the node that | corresponds to the node that | ||
contains the document as a whole. | contains the document as a whole. | ||
You can insert additional nodes, either by deserializing a character stream | You can insert additional nodes, either by deserializing a character stream | ||
containing an XML document instance (for example, with WebReceive), | containing an XML document instance (for example, with <var>WebReceive</var>), | ||
or by using Add*/Insert*Before methods to insert nodes. | or by using <var>Add</var>*/<var>Insert</var>*<var>Before</var> methods to insert nodes. | ||
The children of the Root node are the “top-level” element and any top-level | The children of the <var>Root</var> node are the “top-level” element and any top-level | ||
processing instructions and/or comments that precede or follow it. | processing instructions and/or comments that precede or follow it. | ||
Do not confuse the Root node, which is the root | Do not confuse the <var>Root</var> node, which is the root | ||
of the XmlDoc tree, with the top-level element of the XML document. | of the XmlDoc tree, with the top-level element of the XML document. | ||
====XmlDoc states==== | ====XmlDoc states==== | ||
An XmlDoc can have one of the following three states: | An <var>XmlDoc</var> can have one of the following three states: | ||
<dl> | <dl> | ||
<dt>EMPTY | <dt>EMPTY | ||
<dd>An XmlDoc in this state has no nodes other than the Root node. | <dd>An <var>XmlDoc</var> in this state has no nodes other than the <var>Root</var> node. | ||
This is the state of an XmlDoc as returned by the | This is the state of an <var>XmlDoc</var> as returned by the <var>XmlDoc</var> | ||
<var>New</var> method. | |||
<dt>WELL-FORMED | <dt>WELL-FORMED | ||
<dd>An XmlDoc in this state contains at least the top-level Element node. | <dd>An <var>XmlDoc</var> in this state contains at least the top-level <var>Element</var> node. | ||
<dt>Non-EMPTY not WELL-FORMED | <dt>Non-EMPTY not WELL-FORMED | ||
<dd>An XmlDoc in this state contains at least one Comment or | <dd>An <var>XmlDoc</var> in this state contains at least one <var>Comment</var> or <var>Pi</var> | ||
node but no Element nodes. | node but no <var>Element</var> nodes. | ||
</dl> | </dl> | ||
Note that only an XmlDoc in the WELL-FORMED state may be | Note that only an <var>XmlDoc</var> in the WELL-FORMED state may be | ||
converted into a '''complete''' text representation of an XmlDoc, and that | converted into a '''complete''' text representation of an <var>XmlDoc</var>, and that | ||
you can only use an EMPTY XmlDoc as the target of “deserializing” the | you can only use an EMPTY <var>XmlDoc</var> as the target of “deserializing” the | ||
text representation of an XML document. | text representation of an XML document. | ||
===The XmlNode and XmlNodelist classes, and XPath=== | ===The XmlNode and XmlNodelist classes, and XPath=== | ||
<!-- on XmlNode/list class page, #REDIRECT [[XmlDoc API#The XmlNode and XmlNodelist classes, and XPath]] --> | <!-- on XmlNode/list class page, #REDIRECT [[XmlDoc API#The XmlNode and XmlNodelist classes, and XPath]] --> | ||
In addition to using an XmlDoc directly, | In addition to using an <var>XmlDoc</var> directly, | ||
you can access an XmlDoc with either of the following objects: | you can access an XmlDoc with either of the following objects: | ||
<ul> | <ul> | ||
<li>An | <li>An <b><var>XmlNode</var></b>, which is a single pointer to a node in an <var>XmlDoc</var> | ||
<li>An | <li>An <b><var>XmlNodelist</var></b>, which contains a | ||
list of pointers to nodes selected from an XmlDoc | list of pointers to nodes selected from an <var>XmlDoc</var> | ||
</ul> | </ul> | ||
Instances of both of these objects are created by and returned as the | Instances of both of these objects are created by and returned as the | ||
value of several XmlDoc API functions. | value of several <var>XmlDoc</var> API functions. | ||
An XmlNodelist may also be created by an invocation of | An <var>XmlNodelist</var> may also be created by an invocation of | ||
the XmlNodelist [[New (XmlDoc/XmlNodelist constructor)|New]] constructor, | the <var>XmlNodelist</var> <var>[[New (XmlDoc/XmlNodelist constructor)|New]]</var> constructor, | ||
which requires the specification of an XmlDoc argument | which requires the specification of an <var>XmlDoc</var> argument | ||
— the XmlDoc with which the XmlNodelist is associated. | — the <var>XmlDoc</var> with which the <var>XmlNodelist</var> is associated. | ||
There is '''not''' a <var>New</var> constructor in the | |||
New constructor. | <var>XmlNode</var> class. | ||
A single XmlDoc can have any number of | A single <var>XmlDoc</var> can have any number of <var>XmlNodelist</var>s and <var>XmlNode</var>s associated with it. | ||
Most operations on the “contents” of an XmlDoc | Most operations on the “contents” of an <var>XmlDoc</var> | ||
select one or more nodes using '''XPath''' expressions | select one or more nodes using '''XPath''' expressions | ||
(“PathExpr” is the XPath syntax term, as explained in | (“PathExpr” is the XPath syntax term, as explained in | ||
"[[XML processing in Janus SOAP#XPath syntax|XPath syntax]]". | "[[XML processing in Janus SOAP#XPath syntax|XPath syntax]]". | ||
All methods that accept an XPath LocationPath expression argument are | All methods that accept an XPath LocationPath expression argument are | ||
members of both the XmlDoc and the XmlNode classes. | members of both the <var>XmlDoc</var> and the <var>XmlNode</var> classes. | ||
There are two forms of XPath expressions: | There are two forms of XPath expressions: | ||
<dl> | <dl> | ||
<dt>Absolute XPath expression | <dt>Absolute XPath expression | ||
<dd>An absolute XPath expression selects nodes from an XmlDoc, starting at | <dd>An absolute XPath expression selects nodes from an <var>XmlDoc</var>, starting at | ||
the Root node. | the <var>Root</var> node. | ||
The syntax of an absolute XPath expression begins with a forward slash ( / ). | The syntax of an absolute XPath expression begins with a forward slash (<code>/</code>). | ||
<dt>Relative XPath expression | <dt>Relative XPath expression | ||
<dd>A relative XPath expression selects nodes from an XmlDoc, starting from | <dd>A relative XPath expression selects nodes from an <var>XmlDoc</var>, starting from | ||
a '''context | a '''context | ||
node''' which is determined when the expression is used. | node''' which is determined when the expression is used. | ||
Line 248: | Line 250: | ||
(the type of object on which the method operates) of the invocation: | (the type of object on which the method operates) of the invocation: | ||
<ol> | <ol> | ||
<li>If the method object is an XmlDoc, the context node is the Root node. | <li>If the method object is an <var>XmlDoc</var>, the context node is the <var>Root</var> node. | ||
<li>If the method object is an XmlNode, the context node is the node which it | <li>If the method object is an <var>XmlNode</var>, the context node is the node which it | ||
points to. | points to. | ||
</ol> | </ol> | ||
</dl> | </dl> | ||
In addition to operating on the contents of an XmlDoc, there are several methods | In addition to operating on the contents of an <var>XmlDoc</var>, there are several methods | ||
(for example, [[WebReceive (XmlDoc function)|WebReceive]]) that operate on the XmlDoc | (for example, <var>[[WebReceive (XmlDoc function)|WebReceive]]</var>) that operate on the <var>XmlDoc</var> | ||
as a whole. | as a whole. | ||
These methods only allow an XmlDoc method object. | These methods only allow an <var>XmlDoc</var> method object. | ||
If you need to obtain the XmlDoc associated with an XmlNode or XmlNodelist, | If you need to obtain the <var>XmlDoc</var> associated with an <var>XmlNode</var> or <var>XmlNodelist</var>, | ||
use the [[XmlDoc (XmlNode/XmlNodelist function)|XmlDoc]] function. | use the <var>[[XmlDoc (XmlNode/XmlNodelist function)|XmlDoc]]</var> function. | ||
The [[#An example of XmlDoc methods and XPath|following section]] continues the explanation of | The [[#An example of XmlDoc methods and XPath|following section]] continues the explanation of | ||
XPath, | XPath, <var>XmlNode</var>s, and <var>XmlNodelist</var>s. | ||
Further information about XPath expressions and | Further information about XPath expressions and | ||
node sets is also contained in [[XPath]]. | node sets is also contained in [[XPath]]. | ||
===An example of XmlDoc API methods and XPath=== | ===An example of XmlDoc API methods and XPath=== | ||
This section illustrates a small XML document received as a web request, | This section illustrates a small XML document received as a web request, | ||
followed by part of a User Language request that uses some XmlDoc | followed by part of a <var class="product">User Language</var> request that uses some <var>XmlDoc</var> | ||
API methods, | API methods, | ||
with particular attention to the method's XPath arguments. | with particular attention to the method's XPath arguments. | ||
Line 287: | Line 289: | ||
</pre> | </pre> | ||
Here is some User Language which could be used to receive and process this | Here is some <var class="product">User Language</var> which could be used to receive and process this | ||
request: | request: | ||
<pre> | <pre> | ||
Line 308: | Line 310: | ||
</pre> | </pre> | ||
Value and SelectNodes, | <var>Value</var> and <var>SelectNodes</var>, | ||
like many methods in the XmlDoc API, have an optional argument | like many methods in the <var>XmlDoc</var> API, have an optional argument | ||
that allows you to process any of the nodes in an XmlDoc, | that allows you to process any of the nodes in an <var>XmlDoc</var>, | ||
rather than the default, which is to process the node to which the method | rather than the default, which is to process the node to which the method | ||
object points. | object points. | ||
Line 316: | Line 318: | ||
The optional argument shown above is an XPath | The optional argument shown above is an XPath | ||
expression (for | expression (for | ||
SelectNodes, < | <var>SelectNodes</var>, <code>/purchase_order/pitm</code>; for <var>Value</var>, <code>partnum</code> and | ||
< | <code>qty</code>). | ||
An XPath expression selects a list of nodes, | An XPath expression selects a list of nodes, | ||
starting either from the XmlDoc | starting either from the <var>XmlDoc</var> <var>Root</var> (when an '''absolute''' | ||
Xpath expression is used) | Xpath expression is used) | ||
or from a particular context node in an XmlDoc (when a '''relative''' | or from a particular context node in an <var>XmlDoc</var> (when a '''relative''' | ||
Xpath expression is used). | Xpath expression is used). | ||
Syntactically, an XPath expression that begins with a slash | Syntactically, an XPath expression that begins with a slash | ||
< | (<code>/</code>) is absolute. | ||
SelectNodes returns the entire result of its XPath expression | <var>SelectNodes</var> returns the entire result of its XPath expression | ||
argument. | argument. | ||
Many other XmlDoc API | Many other <var>XmlDoc</var> API | ||
methods, however, operate on the first of the nodes resulting from the | methods, however, operate on the first of the nodes resulting from the | ||
argument's XPath expression. | argument's XPath expression. | ||
Line 337: | Line 338: | ||
order” (see | order” (see | ||
"[[XPath#Order of nodes: node sets versus nodelists|Order of nodes: node sets versus nodelists]]"). | "[[XPath#Order of nodes: node sets versus nodelists|Order of nodes: node sets versus nodelists]]"). | ||
===Updating=== | ===Updating=== | ||
Updating an XmlDoc generally refers to the addition and deletion | Updating an <var>XmlDoc</var> generally refers to the addition and deletion | ||
of the nodes of the XmlDoc tree, which includes the generation | of the nodes of the <var>XmlDoc</var> tree, which includes the generation | ||
of the document's initial contents. | of the document's initial contents. | ||
The initial | The initial | ||
contents of an XmlDoc can be established by one of the deserialization methods: | contents of an <var>XmlDoc</var> can be established by one of the deserialization methods: | ||
[[LoadXml (XmlDoc/XmlNode function)|LoadXml]], [[WebReceive (XmlDoc function)|WebReceive]], or | <var>[[LoadXml (XmlDoc/XmlNode function)|LoadXml]]</var>, <var>[[WebReceive (XmlDoc function)|WebReceive]]</var>, or | ||
[[ParseXml (HttpResponse function)|ParseXml]]. | <var>[[ParseXml (HttpResponse function)|ParseXml]]</var>. | ||
Whether you use a method to set the “initial” contents | Whether you use a method to set the “initial” contents | ||
of an XmlDoc or whether you start with | of an <var>XmlDoc</var> or whether you start with | ||
an EMPTY XmlDoc, you can then insert nodes into it, using one or more of the | an EMPTY <var>XmlDoc</var>, you can then insert nodes into it, using one or more of the | ||
methods whose | methods whose | ||
name begins with “Add,” such as [[AddElement (XmlDoc/XmlNode function)|AddElement]] | name begins with “<var>Add</var>,” such as <var>[[AddElement (XmlDoc/XmlNode function)|AddElement]]</var> | ||
or whose name begins with “Insert,” | or whose name begins with “<var>Insert</var>,” | ||
such as [[InsertSubtreeBefore (XmlNode function)|InsertSubtreeBefore]]. | such as <var>[[InsertSubtreeBefore (XmlNode function)|InsertSubtreeBefore]]</var>. | ||
Once an XmlDoc has one or more nodes in addition to the Root node, you | Once an <var>XmlDoc</var> has one or more nodes in addition to the <var>Root</var> node, you | ||
can modify the [[Value (XmlDoc/XmlNode property)|Value]] of Text and other nodes, and you | can modify the <var>[[Value (XmlDoc/XmlNode property)|Value]]</var> of <var>Text</var> and other nodes, and you | ||
can delete nodes from it using [[DeleteSubtree (XmlDoc/XmlNode subroutine)|DeleteSubtree]]. | can delete nodes from it using <var>[[DeleteSubtree (XmlDoc/XmlNode subroutine)|DeleteSubtree]]</var>. | ||
====Inserting nodes and copying subtrees==== | ====Inserting nodes and copying subtrees==== | ||
The Add* methods are designed to make it easy to “append” nodes to an | The <var>Add</var>* methods are designed to make it easy to “append” nodes to an | ||
XmlDoc in a “depth-first, left-to-right” order in the simple case. | <var>XmlDoc</var> in a “depth-first, left-to-right” order in the simple case. | ||
These methods insert a node as the '''last''' child of the | These methods insert a node as the '''last''' child of the | ||
node pointed to by the method object. | node pointed to by the method object. | ||
Most of the Add* methods (for example AddElement) have Insert*Before | Most of the <var>Add</var>* methods (for example <var>AddElement</var>) have <var>Insert</var>*<var>Before</var> | ||
counterparts (for example, InsertElementBefore) | counterparts (for example, <var>InsertElementBefore</var>) | ||
which | which | ||
insert a node in a position other than the last child of an Element or the Root. | insert a node in a position other than the last child of an <var>Element</var> or the <var>Root</var>. | ||
AddAttribute and AddNamespace are the exceptions, without an Insert*Before counterpart. | <var>AddAttribute</var> and <var>AddNamespace</var> are the exceptions, without an <var>Insert</var>*<var>Before</var> counterpart. | ||
AddElement (as does InsertElementBefore) has an optional text value | <var>AddElement</var> (as does <var>InsertElementBefore</var>) has an optional text value | ||
argument, with which you can | argument, with which you can | ||
insert a Text node child of the inserted Element | insert a <var>Text</var> node child of the inserted <var>Element</var> node. | ||
< | |||
Here is an example of the updating methods in the XmlDoc API: | Here is an example of the updating methods in the <var>XmlDoc</var> API: | ||
<pre> | <pre> | ||
%doc Object XmlDoc | %doc Object XmlDoc | ||
Line 401: | Line 400: | ||
</pre> | </pre> | ||
====Namespaces with Add* and Insert* methods==== | ====Namespaces with Add* and Insert* methods==== | ||
When an XmlDoc is deserialized, the namespace declarations (and the use of | When an <var>XmlDoc</var> is deserialized, the namespace declarations (and the use of | ||
those declarations by names in the document) follow the scope rules outlined | those declarations by names in the document) follow the scope rules outlined | ||
in "[[XML processing in Janus SOAP#Name and namespace syntax|Name and namespace syntax]]". | in "[[XML processing in Janus SOAP#Name and namespace syntax|Name and namespace syntax]]". | ||
This section explains the namespace structure that results from the updating | This section explains the namespace structure that results from the updating | ||
(adding and removing nodes) of an XmlDoc. | (adding and removing nodes) of an <var>XmlDoc</var>. | ||
Most of these updating methods are the Add* and Insert*Before methods | Most of these updating methods are the <var>Add</var>* and <var>Insert</var>*<var>Before</var> methods | ||
(described individually in the [[List of XmlDoc API methods]]). | (described individually in the [[List of XmlDoc API methods]]). | ||
In the following | In the following | ||
discussion, all references to an Add* method (for example, AddElement) refer | discussion, all references to an <var>Add</var>* method (for example, <var>AddElement</var>) refer | ||
equally to the corresponding Insert*Before method (for example, InsertElementBefore). | equally to the corresponding <var>Insert</var>*<var>Before</var> method (for example, <var>InsertElementBefore</var>). | ||
<ul> | <ul> | ||
<li>From deserialization through serialization, the XmlDoc API | <li>From deserialization through serialization, the <var>XmlDoc</var> API | ||
enforces the syntax rules of | enforces the syntax rules of | ||
[[#Well-formed documents and validation|well-formed documents]]. | [[#Well-formed documents and validation|well-formed documents]]. | ||
When namespace handling is in effect for an XmlDoc | When namespace handling is in effect for an <var>XmlDoc</var> | ||
(Namespace property setting is < | (that is, the | ||
<var>Namespace</var> property setting is <code>On</code>, the default), the prefixes of names of nodes | |||
you add must be declared. | you add must be declared. | ||
<li>Once an attribute or element is added, its URI is fixed | <li>Once an attribute or element is added, its URI is fixed | ||
and will not change thereafter. | and will not change thereafter. | ||
<li>To allow AddElement to add an element with a | <li>To allow <var>AddElement</var> to add an element with a | ||
prefix/URI declaration other than that which is in scope, | prefix/URI declaration other than that which is in scope, | ||
it has a URI argument, which specifies the URI | it has a URI argument, which specifies the URI | ||
Line 428: | Line 428: | ||
a namespace declaration (because it differs from what is in scope), a | a namespace declaration (because it differs from what is in scope), a | ||
declaration is created at the element. | declaration is created at the element. | ||
<li>The URI argument of AddElement can also be such that the application logic | <li>The URI argument of <var>AddElement</var> can also be such that the application logic | ||
around AddElement does not need to depend on whether the prefix/URI declaration | around <var>AddElement</var> does not need to depend on whether the prefix/URI declaration | ||
is already in scope. | is already in scope. | ||
AddAttribute has a URI argument for the same reason, and it can also result in | <var>AddAttribute</var> has a URI argument for the same reason, and it can also result in | ||
the creation of a namespace declaration at the Element parent of the | the creation of a namespace declaration at the <var>Element</var> parent of the | ||
inserted Attribute node. | inserted <var>Attribute</var> node. | ||
<li>As an alternative to the URI argument on | <li>As an alternative to the URI argument on <var>AddElement</var> and <var>AddAttribute</var>, a | ||
namespace declaration is created at an element with the AddNamespace method. | namespace declaration is created at an element with the <var>AddNamespace</var> method. | ||
AddNamespace also lets you insert a namespace declaration that is not used by | <var>AddNamespace</var> also lets you insert a namespace declaration that is not used by | ||
an element nor any of its attributes. | an element nor any of its attributes. | ||
For example, the following fragment: | For example, the following fragment: | ||
Line 454: | Line 454: | ||
</a> | </a> | ||
</pre> | </pre> | ||
<li>When the AddSubtree method copies between different | <li>When the <var>AddSubtree</var> method copies between different <var>XmlDoc</var>s, it does not allow | ||
the source and target | the source and target <var>XmlDoc</var>s to have different <var>Namespace</var> property | ||
settings (doing so could require re-parsing names in some cases). | settings (doing so could require re-parsing names in some cases). | ||
<li>The namespace axis is not allowed in an XPath expression. | <li>The namespace axis is not allowed in an XPath expression. | ||
Line 462: | Line 462: | ||
cannot be "changed out from under". | cannot be "changed out from under". | ||
You can obtain the information in a namespace declaration, however, using | You can obtain the information in a namespace declaration, however, using | ||
certain XmlDoc API methods (for example, the | certain <var>XmlDoc</var> API methods (for example, the <var>Uri</var> property of an <var>XmlNode</var>). | ||
</ul> | </ul> | ||
====Deleting nodes==== | ====Deleting nodes==== | ||
The XmlDoc API subroutine used to delete individual nodes (and their descendants) | The <var>XmlDoc</var> API subroutine used to delete individual nodes (and their descendants) | ||
from an XmlDoc is [[DeleteSubtree (XmlDoc/XmlNode subroutine)|DeleteSubtree]]. | from an <var>XmlDoc</var> is <var>[[DeleteSubtree (XmlDoc/XmlNode subroutine)|DeleteSubtree]]</var>. | ||
An example is shown below. | An example is shown below. | ||
If a node you delete | If a node you delete | ||
was referenced by an XmlNode, the value of that | was referenced by an <var>XmlNode</var>, the value of that | ||
XmlNode becomes Null. | <var>XmlNode</var> becomes <var>Null</var>. | ||
Similarly, | Similarly, | ||
if any deleted nodes were referenced by an item of an XmlNodelist, | if any deleted nodes were referenced by an item of an <var>XmlNodelist</var>, | ||
the value of that item of the XmlNodelist becomes Null. | the value of that item of the <var>XmlNodelist</var> becomes <var>Null</var>. | ||
If you need to “clean up” an XmlNodelist that refers to a deleted XmlDoc | If you need to “clean up” an <var>XmlNodelist</var> that refers to a deleted <var>XmlDoc</var> | ||
node, you can use the [[Difference (XmlNodelist function)|Difference]] function, | node, you can use the <var>[[Difference (XmlNodelist function)|Difference]]</var> function, | ||
as shown in the following example. | as shown in the following example. | ||
In the example, the XmlNodelist object (%nlis) is cleaned up | In the example, the <var>XmlNodelist</var> object (<code>%nlis</code>) is cleaned up | ||
(with Difference) to remove the second item from the | (with <var>Difference</var>) to remove the second item from the | ||
nodelist before referencing the nodelist items. | nodelist before referencing the nodelist items. | ||
The reference to the nodelist items | The reference to the nodelist items | ||
uses relative XPath (the < | uses relative XPath (the <code>'@auth'</code> | ||
argument of the Value method invocation, selecting attributes named | argument of the <var>Value</var> method invocation, selecting attributes named | ||
<code>auth</code>). | |||
<pre> | <pre> | ||
%nlis Object XmlNodelist | %nlis Object XmlNodelist | ||
Line 511: | Line 511: | ||
====Namespace URI for XPath prefixes==== | ====Namespace URI for XPath prefixes==== | ||
It is important to realize that the URI associated with a prefix | It is important to realize that the URI associated with a prefix | ||
<i><b>in the XML document</b></i> is controlled by the < | <i><b>in the XML document</b></i> is controlled by the <code>xmlns</code> | ||
namespace declarations in the document. | namespace declarations in the document. | ||
However, when a prefix is used in a name in an XPath argument to | However, when a prefix is used in a name in an XPath argument to | ||
an XmlDoc API method, the URI for that prefix must be established | an <var>XmlDoc</var> API method, the URI for that prefix must be established | ||
so that the full XPath name (local part and URI namespace) | so that the full XPath name (local part and URI namespace) | ||
can be used to locate a document element. | can be used to locate a document element. | ||
This association of XPath prefixes to URIs is established using | This association of XPath prefixes to URIs is established using | ||
the [[SelectionNamespace (XmlDoc property)|SelectionNamespace property]]. | the <var>[[SelectionNamespace (XmlDoc property)|SelectionNamespace property]]</var>. | ||
The prefix names | The prefix names | ||
Line 532: | Line 532: | ||
<ul> | <ul> | ||
<li>Receiving XML involves converting the information from the character, | <li>Receiving XML involves converting the information from the character, | ||
marked-up form of an XML document into an XmlDoc; | marked-up form of an XML document into an <var>XmlDoc</var>; | ||
this operation is called '''deserialization'''. | this operation is called '''deserialization'''. | ||
<ul> | <ul> | ||
<li>The [[WebReceive (XmlDoc function)|WebReceive]] function | <li>The <var>[[WebReceive (XmlDoc function)|WebReceive]]</var> function | ||
is designed to receive an XML document that has arrived as a web request. | is designed to receive an XML document that has arrived as a web request. | ||
<li>The [[ParseXml (HttpResponse function)|ParseXml]] | <li>The <var>[[ParseXml (HttpResponse function)|ParseXml]]</var> | ||
function of the HttpResponse class accomplishes this for | function of the <var>HttpResponse</var> class accomplishes this for | ||
HTTP clients. | HTTP clients. | ||
<li>For other transport mechanisms, such as | <li>For other transport mechanisms, such as <var class="product">Model 204</var> MQ Series, | ||
the character-format XML document can be placed into a | the character-format XML document can be placed into a longstring, | ||
and the [[LoadXml (XmlDoc/XmlNode function)|LoadXml]] function | and the <var>[[LoadXml (XmlDoc/XmlNode function)|LoadXml]]</var> function | ||
then places the information into an XmlDoc. | then places the information into an <var>XmlDoc</var>. | ||
</ul> | </ul> | ||
<li>Sending XML involves converting the information in an XmlDoc to a | <li>Sending XML involves converting the information in an <var>XmlDoc</var> to a | ||
character stream, including markup such as element tags; | character stream, including markup such as element tags; | ||
this operation is called '''serialization'''. | this operation is called '''serialization'''. | ||
<ul> | <ul> | ||
<li>The [[WebSend (XmlDoc subroutine)|WebSend]] subroutine | <li>The <var>[[WebSend (XmlDoc subroutine)|WebSend]]</var> subroutine | ||
is designed to send an XML document as a web response. | is designed to send an XML document as a web response. | ||
<li>The AddXml method of the HttpRequest class accomplishes this for | <li>The <var>[[AddXml (HttpRequest subroutine)|AddXml]]</var> method of the <var>[[HttpRequest class|HttpRequest]]</var> class accomplishes this for | ||
HTTP clients. | HTTP clients. | ||
<li>For other transport mechanisms, such as | <li>For other transport mechanisms, such as <var class="product">Model 204</var> MQ Series, | ||
the [[Serial (XmlDoc/XmlNode function)|Serial]] function is used to | the <var>[[Serial (XmlDoc/XmlNode function)|Serial]]</var> function is used to | ||
place the serialized form into a Longstring, which can then be sent. | place the serialized form into a Longstring, which can then be sent. | ||
</ul> | </ul> | ||
Line 562: | Line 562: | ||
About encoding: | About encoding: | ||
<ul> | <ul> | ||
<li>When the internal representation of an XmlDoc is EBCDIC (prior to | <li>When the internal representation of an <var>XmlDoc</var> is EBCDIC (prior to <var class="product">Sirius Mods</var> | ||
7.6), the deserialization methods | 7.6), the deserialization methods | ||
reject a document if it contains an ISO-10646 (Unicode) character | reject a document if it contains an ISO-10646 (Unicode) character | ||
that cannot be represented in EBCDIC. | that cannot be represented in EBCDIC. | ||
When the internal representation of an XmlDoc is Unicode ( | When the internal representation of an <var>XmlDoc</var> is Unicode (<var class="product">Sirius Mods</var> 7.6 and | ||
higher), the deserialization methods by default reject a document if it contains | higher), the deserialization methods by default reject a document if it contains | ||
a Unicode character that is not translatable to EBCDIC. | a Unicode character that is not translatable to EBCDIC. | ||
Line 573: | Line 573: | ||
See [[#Char and Reference|Char and Reference]] for more information about characters in an XML document. | See [[#Char and Reference|Char and Reference]] for more information about characters in an XML document. | ||
<li>The encodings that are accepted in the deserialization operations | <li>The encodings that are accepted in the deserialization operations | ||
are UTF-8 and UTF-16, and ISO-8859-<i>n</i> (where <i>n</i> is a digit | are <code>UTF-8</code> and <code>UTF-16</code>, and <code>ISO-8859-<i>n</i></code> (where <i>n</i> is a digit | ||
from 1 to 9). | from 1 to 9). | ||
Prior to | Prior to <var class="product">Sirius Mods</var> Version 7.6, | ||
all of the ISO-8859-<i>n</i> variants are treated as ISO-8859-1. | all of the <code>ISO-8859-<i>n</i></code> variants are treated as <code>ISO-8859-1</code>. | ||
As of | As of <var class="product">Sirius Mods</var> 7.6, the variants determine Ascii to Unicode conversions | ||
according to the specification of the individual variant. | according to the specification of the individual variant. | ||
'''Note:''' | '''Note:''' | ||
Line 584: | Line 584: | ||
the UTF-8 encoding. | the UTF-8 encoding. | ||
Therefore, | Therefore, | ||
the only values permitted to be set for the [[Encoding (XmlDoc property)|Encoding]] property | the only values permitted to be set for the <var>[[Encoding (XmlDoc property)|Encoding]]</var> property | ||
are UTF-8 and the null string; | are <code>UTF-8</code> and the null string; | ||
in that, see the [[Encoding (XmlDoc property)#Usage Notes|Usage Notes]] | in that, see the <var>[[Encoding (XmlDoc property)#Usage Notes|Usage Notes]]</var> | ||
for more information about the character sets allowed in | for more information about the character sets allowed in | ||
a serialized input XML document and the value of < | a serialized input XML document and the value of <code>encoding</code> in an XML | ||
declaration. | declaration. | ||
</ul> | </ul> | ||
===Strings and Unicode with the XmlDoc API=== | ===Strings and Unicode with the XmlDoc API=== | ||
As of | As of <var class="product">Sirius Mods</var> version 7.6, <var>XmlDoc</var>s are maintained in Unicode | ||
rather than EBCDIC; this is true for all string values, names, prefixes, | rather than EBCDIC; this is true for all string values, names, prefixes, | ||
and URIs. | and URIs. | ||
As a consequence, most of the arguments and results | As a consequence, most of the arguments and results | ||
of the XmlDoc API methods that formerly were | of the <var>XmlDoc</var> API methods that formerly were strings or longstrings are | ||
Unicode strings as of version 7.6. | <var>Unicode</var> strings as of version 7.6. | ||
This switch to Unicode requires little or no change to most | This switch to Unicode requires little or no change to most | ||
existing XmlDoc API applications, however: | existing <var>XmlDoc</var> API applications, however: | ||
XmlDoc API argument and result variables declared as String or Longstring | <var>XmlDoc</var> API argument and result variables declared as <var>String</var> or <var>Longstring</var> | ||
are automatically converted from EBCDIC to Unicode by the | are automatically converted from EBCDIC to Unicode by the <var class="product">Sirius Mods</var>. | ||
For example, the EBCDIC character strings in the arguments in a statement | For example, the EBCDIC character strings in the arguments in a statement | ||
like the following are automatically converted to Unicode: | like the following are automatically converted to Unicode: | ||
Line 611: | Line 611: | ||
Similarly, | Similarly, | ||
if the variable < | if the variable <code>%str</code>, below, was declared as type <var>String</var> or | ||
Longstring, then the Unicode result of the Value method is automatically | <var>Longstring</var>, then the Unicode result of the <var>Value</var> method is automatically | ||
converted to EBCDIC when it is stored in < | converted to EBCDIC when it is stored in <code>%str</code>: | ||
<pre> | <pre> | ||
%str = %n:Value | %str = %n:Value | ||
Line 623: | Line 623: | ||
You can now | You can now | ||
store string values that are not translatable to EBCDIC — | store string values that are not translatable to EBCDIC — | ||
<var class="product">Sirius Mods</var> 7.5 allows storage | |||
only of (most) non-null EBCDIC characters or of characters | only of (most) non-null EBCDIC characters or of characters | ||
that translate to those EBCDIC characters. | that translate to those EBCDIC characters. | ||
Line 629: | Line 629: | ||
The automatic EBCDIC/Unicode conversions described above will not | The automatic EBCDIC/Unicode conversions described above will not | ||
cause request cancellations in requests that run successfully under | cause request cancellations in requests that run successfully under | ||
<var class="product">Sirius Mods</var> 7.5. | |||
But there are other changes to or effects on the XmlDoc API that are due | But there are other changes to or effects on the <var>XmlDoc</var> API that are due | ||
to the switch to Unicode maintenance | to the switch to Unicode maintenance | ||
(the | (the <var class="product">Sirius Mods</var> Release 7.6 Notes | ||
and the individual method descriptions | and the individual method descriptions | ||
provide additional details): | provide additional details): | ||
<ul> | <ul> | ||
<li>The workaround (InvalidChar method) for accommodating nulls and EBCDIC | <li>The workaround (<var>InvalidChar</var> method) for accommodating nulls and EBCDIC | ||
characters that are not allowed by the XML standard is replaced by: | characters that are not allowed by the XML standard is replaced by: | ||
<ul> | <ul> | ||
<li>The [[AllowNull (XmlDoc property)|AllowNull]] property can | <li>The <var>[[AllowNull (XmlDoc property)|AllowNull]]</var> property can | ||
let nulls be stored in an XmlDoc. | let nulls be stored in an <var>XmlDoc</var>. | ||
<li>A method argument (< | <li>A method argument (<var>AllowUntranslatable</var>) | ||
of the deserialization methods that lets you | of the deserialization methods that lets you | ||
store Unicode characters that do not translate to EBCDIC. | store Unicode characters that do not translate to EBCDIC. | ||
Such characters may be also stored directly by the Add* and Insert* methods | Such characters may be also stored directly by the <var>Add</var>* and <var>Insert</var>* methods | ||
of the XmlDoc API; these methods do not require a special argument. | of the <var>XmlDoc</var> API; these methods do not require a special argument. | ||
EBCDIC characters that do not translate to Unicode | EBCDIC characters that do not translate to Unicode | ||
must be handled before they are passed to an XmlDoc update operation. | must be handled before they are passed to an <var>XmlDoc</var> update operation. | ||
For example, EBCDIC X'04' is the SEL (“Select”) control character. | For example, EBCDIC X'04' is the SEL (“Select”) control character. | ||
Since there is no “Select” control character in Unicode, there is no mapping | Since there is no “Select” control character in Unicode, there is no mapping | ||
between EBCDIC X'04' and any Unicode character. | between EBCDIC X'04' and any Unicode character. | ||
For this you might use | For this you might use | ||
the < | the <var>Untranslatable</var> parameter of the | ||
[[EbcdicToUnicode (String function)|EbcdicToUnicode]] function. | <var>[[EbcdicToUnicode (String function)|EbcdicToUnicode]]</var> function. | ||
</ul> | </ul> | ||
<li>If you have defined uninvertible translations ([[??]] refid=ucdinv.), | <li>If you have defined uninvertible translations ([[??]] refid=ucdinv.), | ||
the implicit translation of EBCDIC string arguments and results to Unicode | the implicit translation of EBCDIC string arguments and results to Unicode | ||
as of version 7.6 of the | as of version 7.6 of the <var class="product">Sirius Mods</var> will change the behavior of the | ||
XmlDoc API methods compared to their operation in version 7.5. | <var>XmlDoc</var> API methods compared to their operation in version 7.5. | ||
For example, assume CCAIN establishes codepage 0037 as the base, | For example, assume CCAIN establishes codepage 0037 as the base, | ||
but it also uses the following UNICODE commands ([[??]] refid=ucmd.) | but it also uses the following <var>UNICODE</var> commands ([[??]] refid=ucmd.) | ||
to allow for the codepage 1047 square bracket characters: | to allow for the codepage 1047 square bracket characters: | ||
<pre> | <pre> | ||
Line 669: | Line 669: | ||
</pre> | </pre> | ||
These | These <var>UNICDOE</var> commands cause uninvertible translations. | ||
For example, by the first command, EBCDIC X'AD' translates to U+005B, but | For example, by the first command, EBCDIC X'AD' translates to U+005B, but | ||
by the definition of codepage 0037, U+005B translates to EBCDIC X'BA'. | by the definition of codepage 0037, U+005B translates to EBCDIC X'BA'. | ||
Consequently, you can add a X'AD' character to an XmlDoc, but if you display | Consequently, you can add a X'AD' character to an <var>XmlDoc</var>, but if you display | ||
its value: | its value: | ||
<pre> | <pre> | ||
Line 684: | Line 684: | ||
</pre> | </pre> | ||
The Value method returns the Unicode character U+005B, which is translated | The <var>Value</var> method returns the Unicode character U+005B, which is translated | ||
implicitly to EBCDIC X'BA' as | implicitly to EBCDIC X'BA' as the string input for | ||
[[StringToHex (String function)|StringToHex]]. | <var>[[StringToHex (String function)|StringToHex]]</var>. | ||
In version 7.5, because XmlDoc strings are stored in EBCDIC, | In version 7.5, because <var>XmlDoc</var> strings are stored in EBCDIC, | ||
no implicit translation is performed, and | no implicit translation is performed, and | ||
the result of the above two statements is: | the result of the above two statements is: | ||
Line 694: | Line 694: | ||
AD | AD | ||
</pre> | </pre> | ||
<li>The [[Print (XmlDoc/XmlNode subroutine)|Print]] subroutine | <li>The <var>[[Print (XmlDoc/XmlNode subroutine)|Print]]</var> subroutine | ||
is equipped to display the Unicode values that are stored in | is equipped to display the Unicode values that are stored in <var>XmlDoc</var>s, | ||
even if the Unicode characters are not translatable to EBCDIC. | even if the Unicode characters are not translatable to EBCDIC. | ||
If non-translatable Unicode characters are stored in XmlDoc Attribute or | If non-translatable Unicode characters are stored in <var>XmlDoc</var> <var>Attribute</var> or | ||
Element values, Print displays their XML hexadecimal character references. | <var>Element</var> values, <var>Print</var> displays their XML hexadecimal character references. | ||
If non-translatable Unicode characters are stored in a | If non-translatable Unicode characters are stored in a | ||
context other than Element or Attribute (a name, Comment, or | context other than <var>Element</var> or <var>Attribute</var> (a name, <var>Comment</var>, or <var>Pi</var>), | ||
the Print < | the <var>Print</var> <var>CharacterEncodeAll</var> option is required to display | ||
a character reference and avoid request cancellation. | a character reference and avoid request cancellation. | ||
<li>As described further in [[??]] refid=uniconv., the User Language Print | <li>As described further in [[??]] refid=uniconv., the <var class="product">User Language</var> <var>Print</var> | ||
statement under | statement under <var class="product">Sirius Mods</var> 7.6 does not cancel the request | ||
if it is presented with a Unicode character that does not translate to EBCDIC. | if it is presented with a Unicode character that does not translate to EBCDIC. | ||
If it encounters an untranslatable Unicode character, Print will display | If it encounters an untranslatable Unicode character, <var>Print</var> will display | ||
an EBCDIC string that contains the character's hex encoding. | an EBCDIC string that contains the character's hex encoding. | ||
As an example, consider the direct printing of the output of [[Value (XmlDoc/XmlNode property)|Value]]. | As an example, consider the direct printing of the output of <var>[[Value (XmlDoc/XmlNode property)|Value]]</var>. | ||
Say the element node assigned to %nodeY contains the Unicode | Say the element node assigned to <code>%nodeY</code> contains the Unicode | ||
trademark character (U+2122), which does not translate to EBCDIC. | trademark character (U+2122), which does not translate to EBCDIC. | ||
The following statement succeeds because the Print statement | The following statement succeeds because the <var>Print</var> statement | ||
can handle untranslatable Unicode characters: | can handle untranslatable Unicode characters: | ||
<pre> | <pre> | ||
Line 719: | Line 719: | ||
</pre> | </pre> | ||
The result under | The result under <var class="product">Sirius Mods</var> 7.5 is a request cancellation. | ||
The result under | The result under <var class="product">Sirius Mods</var> 7.6 is: | ||
<pre> | <pre> | ||
&#x2122; | &#x2122; | ||
</pre> | </pre> | ||
However, the following common operation using the StringToHex method | However, the following common operation using the <var>StringToHex</var> method | ||
with Value does '''not''' succeed: | with <var>Value</var> does '''not''' succeed: | ||
<pre> | <pre> | ||
Print %nodeY:Value:stringToHex | Print %nodeY:Value:stringToHex | ||
</pre> | </pre> | ||
When StringToHex attempts to implicitly convert to EBCDIC the Unicode character | When <var>StringToHex</var> attempts to implicitly convert to EBCDIC the Unicode character | ||
passed to it by the Value | passed to it by the <var>Value</var> function, the conversion fails because the character | ||
is not translatable to EBCDIC, and the request is cancelled. | is not translatable to EBCDIC, and the request is cancelled. | ||
Such an implicit conversion, which simply uses the current | Such an implicit conversion, which simply uses the current | ||
Unicode translation tables, does '''not''' do character encoding. | Unicode translation tables, does '''not''' do character encoding. | ||
To avoid a request cancellation here and view the Value result, | To avoid a request cancellation here and view the <var>Value</var> result, | ||
you can use the [[UnicodeToUtf16 (Unicode function)|UnicodeToUtf16]] function | you can use the <var>[[UnicodeToUtf16 (Unicode function)|UnicodeToUtf16]]</var> function | ||
to encode the Unicode character as a UTF-16 string for input to StringToHex: | to encode the Unicode character as a UTF-16 string for input to <var>StringToHex</var>: | ||
<pre> | <pre> | ||
Print %nodeY:Value:unicodeToUtf16:stringToHex | Print %nodeY:Value:unicodeToUtf16:stringToHex | ||
Line 746: | Line 746: | ||
For more information about the characters that are valid | For more information about the characters that are valid | ||
in an XmlDoc API XML document, see [[??]] refid=isoebcd. | in an <var>XmlDoc</var> API XML document, see [[??]] refid=isoebcd. | ||
====Using Longstrings or Unicode instead of Strings==== | ====Using Longstrings or Unicode instead of Strings==== | ||
The Longstring | The <var>Unicode</var> and | ||
<var>Longstring</var> datatypes, described in [[??]] refid=lstr., | |||
provides an atomic type that can contain a string longer than 255 bytes. | provides an atomic type that can contain a string longer than 255 bytes. | ||
The XmlDoc API methods, like all [[Janus SOAP User Language Interface]] methods, accept | The <var>XmlDoc</var> API methods, like all [[Janus SOAP User Language Interface]] methods, accept strings longer than 255 | ||
whenever | |||
they have a string argument or result, which is to say: | they have a string argument or result, which is to say: | ||
<ul> | <ul> | ||
<li>Input values may exceed 255 bytes in length. | <li>Input values may exceed 255 bytes in length. | ||
<li>Various XmlDoc API methods will return a string longer than 255 bytes, | <li>Various <var>XmlDoc</var> API methods will return a string longer than 255 bytes, | ||
if indeed the result value exceeds 255 bytes. | if indeed the result value exceeds 255 bytes. | ||
</ul> | </ul> | ||
The following subsections provide some guidelines to determine when | The following subsections provide some guidelines to determine when | ||
you | you 'must' use a longstring (or <var>Unicode</var>, as of <var class="product">Sirius Mods</var> version 7.6) | ||
%variable or context for a | %variable or context for a string argument or for | ||
the result of a method in the XmlDoc API. | the result of a method in the <var>XmlDoc</var> API. | ||
Since the server table requirements and the processing overhead | Since the server table requirements and the processing overhead | ||
for Longstring or Unicode are just a little more than for a String Len | for <var>Longstring</var> or <var>Unicode</var> are just a little more than for a <code>String Len | ||
255 %variable, it is recommended that you use a Longstring or Unicode in the | 255</code> %variable, it is recommended that you use a <var>Longstring</var> or <var>Unicode</var> in the | ||
XmlDoc API methods wherever you might be using a String Len 255 %variable. | <var>XmlDoc</var> API methods wherever you might be using a <code>String Len 255</code> %variable. | ||
=====Xml and Serial methods===== | =====Xml and Serial methods===== | ||
You should use a Longstring or Unicode %variable to hold the result | You should use a <var>Longstring</var> or <var>Unicode</var> %variable to hold the result | ||
of the Xml or Serial methods — the total concatenated length of all | of the <var>Xml</var> or <var>Serial</var> methods — the total concatenated length of all | ||
markup and character content in a document (or subtree, for Serial) | markup and character content in a document (or subtree, for <var>Serial</var>) | ||
— which will most likely exceed 255 bytes. | — which will most likely exceed 255 bytes. | ||
Thus, the first invocation of the Xml method below will never fail (for length | Thus, the first invocation of the <var>Xml</var> method below will never fail (for length | ||
reasons) but the second will usually cause a request cancellation: | reasons) but the second will usually cause a request cancellation: | ||
<pre> | <pre> | ||
Line 780: | Line 782: | ||
</pre> | </pre> | ||
=====Value[Default] methods===== | =====Value[Default] methods===== | ||
Usually you should use a Longstring or Unicode %variable to hold the | Usually you should use a <var>Longstring</var> or <var>Unicode</var> %variable to hold the | ||
result of the Value or ValueDefault methods. | result of the <var>Value</var> or <var>ValueDefault</var> methods. | ||
For example, | For example, | ||
the first two invocations of the Value method below will succeed | the first two invocations of the <var>Value</var> method below will succeed | ||
but the third will cause a request cancellation: | but the third will cause a request cancellation: | ||
<pre> | <pre> | ||
Line 796: | Line 798: | ||
</pre> | </pre> | ||
As noted above, the best approach here is to use Longstring or Unicode %variables | As noted above, the best approach here is to use <var>Longstring</var> or <var>Unicode</var> %variables | ||
where you might use String Len 255 %variables. | where you might use <code>String Len 255</code> %variables. | ||
=====URI-related methods===== | =====URI-related methods===== | ||
Besides the Xml and Value methods, | Besides the <var>Xml</var> and <var>Value</var> methods, | ||
other XmlDoc API methods either cannot return a value longer | other <var>XmlDoc</var> API methods either cannot return a value longer | ||
than 255 bytes or, with typical XML documents, are unlikely to do so. | than 255 bytes or, with typical XML documents, are unlikely to do so. | ||
If you have a namespace URI that exceeds 255 bytes, | If you have a namespace URI that exceeds 255 bytes, | ||
it may be necessary to use a Longstring or Unicode %variable. | it may be necessary to use a <var>Longstring</var> or <var>Unicode</var> %variable. | ||
For example, | For example, | ||
the first two invocations of the | the first two invocations of the <var>Uri</var> method below will succeed, | ||
but the third will cause a request cancellation: | but the third will cause a request cancellation: | ||
<pre> | <pre> | ||
Line 818: | Line 820: | ||
</pre> | </pre> | ||
As noted above, the easiest approach here is to use Longstring or Unicode | As noted above, the easiest approach here is to use <var>Longstring</var> or <var>Unicode</var> | ||
%variables where you might use String Len 255 %variables. | %variables where you might use <code>String Len 255</code> %variables. | ||
===Conventions and terminology for XmlDoc API methds=== | ===Conventions and terminology for XmlDoc API methds=== | ||
In addition to those described in [[Notation conventions for methods]], | In addition to those described in [[Notation conventions for methods]], | ||
the following conventions are also used in the individual | the following conventions are also used in the individual | ||
XmlDoc API method descriptions: | <var>XmlDoc</var> API method descriptions: | ||
<ul> | <ul> | ||
<li>Symbols used in the syntax include the following. | <li>Symbols used in the syntax include the following. | ||
Line 834: | Line 836: | ||
<dt>nr | <dt>nr | ||
<dd>Denotes an abstract class (short for “node reference”) for methods | <dd>Denotes an abstract class (short for “node reference”) for methods | ||
that operate on a node and that can be used with either an XmlNode or an XmlDoc. | that operate on a node and that can be used with either an <var>XmlNode</var> or an <var>XmlDoc</var>. | ||
If an XmlDoc, the node for the operation is the root node. | If an <var>XmlDoc</var>, the node for the operation is the root node. | ||
<dt>doc | <dt>doc | ||
<dd>Denotes an object of class XmlDoc. | <dd>Denotes an object of class <var>XmlDoc</var>. | ||
<dt>nod | <dt>nod | ||
<dd>Denotes an object of class XmlNode. | <dd>Denotes an object of class <var>XmlNode</var>. | ||
<dt>nlis | <dt>nlis | ||
<dd>Denotes an object of class XmlNodelist. | <dd>Denotes an object of class <var>XmlNodelist</var>. | ||
</dl> | </dl> | ||
<li>Although the terms “XmlNode” and “node” are closely related, | <li>Although the terms “XmlNode” and “node” are closely related, | ||
effort is made to distinguish them as necessary in the method descriptions. | effort is made to distinguish them as necessary in the method descriptions. | ||
An XmlNode is an object that points to a node in an XmlDoc | An <var>XmlNode</var> is an object that points to a node in an <var>XmlDoc</var>. | ||
Similarly, an | Similarly, an <var>XmlNodelist</var> is an object that contains a set, or list, of | ||
<var>XmlNode</var>s selected from a particular <var>XmlDoc</var>. | |||
Strictly speaking, a “nodelist” does not exist, but | Strictly speaking, a “nodelist” does not exist, but | ||
the term is occasionally used as an abbreviation or generalization of XmlNodelist. | the term is occasionally used as an abbreviation or generalization of <var>XmlNodelist</var>. | ||
<li>Null objects, null strings, empty results | <li>Null objects, null strings, empty results | ||
<ul> | <ul> | ||
<li>A | <li>A <var>Null</var> object is one that has been deleted or that has not been | ||
instantiated. | instantiated. | ||
A “null” string is a zero length string value. | A “null” string is a zero length string value. | ||
The text in the method descriptions distinguishes these two terms. | The text in the method descriptions distinguishes these two terms. | ||
<li>Object-type arguments must not be Null, unless that | <li>Object-type arguments must not be <var>Null</var>, unless that | ||
argument explicitly allows | argument explicitly allows <var>Null</var>. | ||
Hence, a Null argument typically causes a request cancellation. | Hence, a <var>Null</var> argument typically causes a request cancellation. | ||
Currently, no XmlDoc API methods allow Null object arguments, | Currently, no <var>XmlDoc</var> API methods allow <var>Null</var> object arguments, | ||
and the “Request Cancellation Errors” section for each method does not | and the “Request Cancellation Errors” section for each method does not | ||
include this condition. | include this condition. | ||
Line 867: | Line 869: | ||
Each method that has an XPath argument will either list the empty XPath result | Each method that has an XPath argument will either list the empty XPath result | ||
as a request cancellation error, or will explain the operation of the method | as a request cancellation error, or will explain the operation of the method | ||
when the XPath result is the empty | when the XPath result is the empty nodeset. | ||
</ul> | </ul> | ||
</ul> | </ul> | ||
[[Category:Overviews]] | [[Category:Overviews]] |
Revision as of 12:40, 17 February 2012
XmlDoc API concepts and data structures
See also: |
The XmlDoc API is based on the use of XML documents. "XML processing in Janus SOAP" and various XML references explain that an XML document can contain any type of data, so an XML document may not be primarily intended for human reading. Nevertheless, an XML document can be simply and meaningfully expressed or represented entirely with readable characters. This character form of an XML document is called the serial form. When operating on an XML document with the XmlDoc API, the serial form is converted to an XmlDoc object.
Only a few categories of operations are needed on XML documents; one way to structure them is:
Receive | Receive the transmitted text of a document and convert it into an XmlDoc, containing nodes to represent the hierarchy of the XML document. |
---|---|
Update | Update or create an XmlDoc, by adding, deleting, copying, or replacing nodes. |
Access | Access nodes in an XmlDoc, and data contained within them. |
Send | Convert an XmlDoc into a textual representation, and transmit it. |
Other | There are other operations, such as XmlDoc properties to control certain operations, data structure housekeeping, and debugging facilities. |
The remainder of this article describes the Janus SOAP User Language Interface objects used to operate on XML documents. It reviews the above categories of operations, showing how they are accommodated by the XmlDoc API classes: XmlDoc, XmlNode, and XmlNodelist. The objects are operated upon by methods which are members of these classes.
Typical operations on an XML document
This section list the categories of operations on an XML document, and provides the motivation for objects in the XmlDoc API: XmlDocs, XmlNodes, and XmlNodelists.
Receive
The process of receiving a document actually consists of two steps:
- Receiving the document text using some “transport” mechanism, such as Janus Web Server (HTTP, as server) Janus Sockets (usually, HTTP, as client), Model 204 MQ Series, access from a file, etc.
- Converting the XML document (deserialization) into its internal representation (an XmlDoc) so that other operations can be performed on it.
If the XML document is received by Janus Web Server, these steps are performed together by the WebReceive function. For the HTTP Helper, the document text is received by the HttpRequest Get, Post or Send function, and the deserialization is done by the HttpResponse ParseXml function. For other forms of transport, the steps are performed separately: the text form of the document is received into a longstring, and the longstring contents are converted into internal form by the LoadXml function.
Update
You modify an XmlDoc using various XmlDoc API methods. If you start with an empty XmlDoc, some methods (the Add* and Insert* methods for various node types) allow you to generate an XmlDoc "directly", without first representing it in the serial text form. You can also update an XmlDoc into which you have received a document.
Access
Since an XML document is a hierarchical structure, your application will need to select some part of the hierarchy to operate upon, for example, to obtain its value. Various XmlDoc API methods do this. In addition, some XmlDoc API updating methods also require that you specify where in the hierarchy an update is performed.
Selecting nodes from an XmlDoc is performed using the XPath language (introduced in XML Path Language (XPath)). XPath can be used for accessing a single node in the document, for example, getting an element node's string value using the Value property. You can also work with lists of selected nodes, represented by XmlNodelists. The SelectNodes function produces such a list. Other XmlNodelist methods also work with them, including the Item function, which gets a single XmlNode from an XmlNodelist. SelectSingleNode returns an XmlNode, as do most of the Add* and Insert*Before methods.
Send
The process of sending a document actually consists of two steps:
- Converting the XmlDoc into its serial text representation.
- Sending the document text using some “transport” mechanism, such as Janus Web Server (HTTP, as server), Janus Sockets (usually, HTTP, as client), Model 204 MQ Series, access from a file, etc.
If the XML document is sent by Janus Web Server, the steps can be performed together by the WebSend subroutine. For the HTTP Helper, the document is serialized by the HttpRequest AddXml subroutine, and the document is sent by the HttpRequest Get, Post, or Send function. For other forms of transport, the steps are performed separately: the XmlDoc is converted into external form by the Serial function and the converted result is sent using the appropriate transport.
Other operations
Some other operations the XmlDoc API methods perform include:
- Creating and initializing an XmlDoc or XmlNodelist.
- Setting or retrieving some property of an XmlDoc, for example, the URI associated with a prefix to be used in an XPath expression (see SelectionNamespace).
- Displaying a document, or some part of it, usually for debugging purposes (see Print).
The XmlDoc class
An XmlDoc object is the internal representation of an XML document; creating one is usually done by invoking the XmlDoc New constructor, which returns an XmlDoc instance. An XmlDoc is a tree structure of nodes. The types of nodes that an XmlDoc may contain are the following (which are enumeration return values of the Type function):
- Attribute
- This type of node is used to represent an attribute of an XML element.
- Comment
- This type of node is used to represent a comment (serialized in the form: <!--comment-->) in an XML document.
- Root
- This type of node is the root of the XmlDoc tree. It has zero or one Element child nodes and any number of Comment and Pi child nodes. Root and Element nodes are the only nodes that can have child nodes.
- Element
- This type of node is used to represent an element in an XML document. Element and Root node ares the only nodes that can have child nodes.
- Pi
- This type of node is used to represent a processing instruction (<?target ...?>) in an XML document. Note: Although the “XML declaration” (<?xml version=...?>) has the same appearance as a processing instruction, it is not a Pi. Also, note that the values of an XmlDoc's XML declaration can be obtained and set with these properties: Version, Encoding, and Standalone.
- Text
- This type of node is used to represent character content within an XML element. Note that a Text node will never contain the null string, and that two Text nodes can be adjacent only if the AdjacentText property is set to allow it.
The XmlDoc node types listed above correspond almost exactly with the structures contained in an XML document (see XML and XML example). The Root node is always present and corresponds to the node that contains the document as a whole. You can insert additional nodes, either by deserializing a character stream containing an XML document instance (for example, with WebReceive), or by using Add*/Insert*Before methods to insert nodes. The children of the Root node are the “top-level” element and any top-level processing instructions and/or comments that precede or follow it. Do not confuse the Root node, which is the root of the XmlDoc tree, with the top-level element of the XML document.
XmlDoc states
An XmlDoc can have one of the following three states:
- EMPTY
- An XmlDoc in this state has no nodes other than the Root node. This is the state of an XmlDoc as returned by the XmlDoc New method.
- WELL-FORMED
- An XmlDoc in this state contains at least the top-level Element node.
- Non-EMPTY not WELL-FORMED
- An XmlDoc in this state contains at least one Comment or Pi node but no Element nodes.
Note that only an XmlDoc in the WELL-FORMED state may be converted into a complete text representation of an XmlDoc, and that you can only use an EMPTY XmlDoc as the target of “deserializing” the text representation of an XML document.
The XmlNode and XmlNodelist classes, and XPath
In addition to using an XmlDoc directly, you can access an XmlDoc with either of the following objects:
- An XmlNode, which is a single pointer to a node in an XmlDoc
- An XmlNodelist, which contains a list of pointers to nodes selected from an XmlDoc
Instances of both of these objects are created by and returned as the value of several XmlDoc API functions. An XmlNodelist may also be created by an invocation of the XmlNodelist New constructor, which requires the specification of an XmlDoc argument — the XmlDoc with which the XmlNodelist is associated. There is not a New constructor in the XmlNode class.
A single XmlDoc can have any number of XmlNodelists and XmlNodes associated with it.
Most operations on the “contents” of an XmlDoc select one or more nodes using XPath expressions (“PathExpr” is the XPath syntax term, as explained in "XPath syntax". All methods that accept an XPath LocationPath expression argument are members of both the XmlDoc and the XmlNode classes.
There are two forms of XPath expressions:
- Absolute XPath expression
- An absolute XPath expression selects nodes from an XmlDoc, starting at
the Root node.
The syntax of an absolute XPath expression begins with a forward slash (
/
). - Relative XPath expression
- A relative XPath expression selects nodes from an XmlDoc, starting from
a context
node which is determined when the expression is used.
The syntax of a relative XPath expression begins with a character other than a slash.
When you use a relative XPath expression,
the context node depends on the method object
(the type of object on which the method operates) of the invocation:
- If the method object is an XmlDoc, the context node is the Root node.
- If the method object is an XmlNode, the context node is the node which it points to.
In addition to operating on the contents of an XmlDoc, there are several methods (for example, WebReceive) that operate on the XmlDoc as a whole. These methods only allow an XmlDoc method object. If you need to obtain the XmlDoc associated with an XmlNode or XmlNodelist, use the XmlDoc function.
The following section continues the explanation of XPath, XmlNodes, and XmlNodelists. Further information about XPath expressions and node sets is also contained in XPath.
An example of XmlDoc API methods and XPath
This section illustrates a small XML document received as a web request, followed by part of a User Language request that uses some XmlDoc API methods, with particular attention to the method's XPath arguments.
Here is the XML document:
<purchase_order> <date>25 July, 2001</date> <pitm> <partnum>1234</partnum> <qty>3</qty> </pitm> <pitm> <partnum>5678</partnum> <qty>2</qty> </pitm> </purchase_order>
Here is some User Language which could be used to receive and process this request:
%doc Object XmlDoc %nl Object XmlNodelist * Create XmlDoc, get web request as contents: %doc = New %doc:WebReceive * Create work nodelist with all pitm elements: %nl = %doc:SelectNodes('/purchase_order/pitm') * Process each pitm: For %j From 1 To %nl:Count %partnum = %nl(%j):Value('partnum') %qty = %nl(%j):Value('qty') ... End For
Value and SelectNodes, like many methods in the XmlDoc API, have an optional argument that allows you to process any of the nodes in an XmlDoc, rather than the default, which is to process the node to which the method object points.
The optional argument shown above is an XPath
expression (for
SelectNodes, /purchase_order/pitm
; for Value, partnum
and
qty
).
An XPath expression selects a list of nodes,
starting either from the XmlDoc Root (when an absolute
Xpath expression is used)
or from a particular context node in an XmlDoc (when a relative
Xpath expression is used).
Syntactically, an XPath expression that begins with a slash
(/
) is absolute.
SelectNodes returns the entire result of its XPath expression argument. Many other XmlDoc API methods, however, operate on the first of the nodes resulting from the argument's XPath expression. That first node is called the head of the argument XPath result. Note that first is defined in terms of “document order” (see "Order of nodes: node sets versus nodelists").
Updating
Updating an XmlDoc generally refers to the addition and deletion of the nodes of the XmlDoc tree, which includes the generation of the document's initial contents. The initial contents of an XmlDoc can be established by one of the deserialization methods: LoadXml, WebReceive, or ParseXml. Whether you use a method to set the “initial” contents of an XmlDoc or whether you start with an EMPTY XmlDoc, you can then insert nodes into it, using one or more of the methods whose name begins with “Add,” such as AddElement or whose name begins with “Insert,” such as InsertSubtreeBefore.
Once an XmlDoc has one or more nodes in addition to the Root node, you can modify the Value of Text and other nodes, and you can delete nodes from it using DeleteSubtree.
Inserting nodes and copying subtrees
The Add* methods are designed to make it easy to “append” nodes to an XmlDoc in a “depth-first, left-to-right” order in the simple case. These methods insert a node as the last child of the node pointed to by the method object.
Most of the Add* methods (for example AddElement) have Insert*Before counterparts (for example, InsertElementBefore) which insert a node in a position other than the last child of an Element or the Root. AddAttribute and AddNamespace are the exceptions, without an Insert*Before counterpart.
AddElement (as does InsertElementBefore) has an optional text value argument, with which you can insert a Text node child of the inserted Element node.
Here is an example of the updating methods in the XmlDoc API:
%doc Object XmlDoc %doc = New %story Object XmlNode %paragraph Object XmlNode %story = %doc:AddElement('story') %story:AddComment('My first XML document') %story:AddElement('greeting', 'Hello, world') %paragraph = %story:AddElement('paragraph') %paragraph:AddElement('line', 'Ask not what') %paragraph:AddElement('line', 'Hear no evil')
This creates the following XML document:
<story> <!--My first XML document--> <greeting>Hello, world!</greeting> <paragraph> <line>Ask not what</line> <line>Hear no evil</line> </paragraph> </story>
Namespaces with Add* and Insert* methods
When an XmlDoc is deserialized, the namespace declarations (and the use of those declarations by names in the document) follow the scope rules outlined in "Name and namespace syntax". This section explains the namespace structure that results from the updating (adding and removing nodes) of an XmlDoc. Most of these updating methods are the Add* and Insert*Before methods (described individually in the List of XmlDoc API methods).
In the following discussion, all references to an Add* method (for example, AddElement) refer equally to the corresponding Insert*Before method (for example, InsertElementBefore).
- From deserialization through serialization, the XmlDoc API
enforces the syntax rules of
well-formed documents.
When namespace handling is in effect for an XmlDoc
(that is, the
Namespace property setting is
On
, the default), the prefixes of names of nodes you add must be declared. - Once an attribute or element is added, its URI is fixed and will not change thereafter.
- To allow AddElement to add an element with a prefix/URI declaration other than that which is in scope, it has a URI argument, which specifies the URI of the element. If the URI argument is used and the resulting prefix/URI combination requires a namespace declaration (because it differs from what is in scope), a declaration is created at the element.
- The URI argument of AddElement can also be such that the application logic around AddElement does not need to depend on whether the prefix/URI declaration is already in scope. AddAttribute has a URI argument for the same reason, and it can also result in the creation of a namespace declaration at the Element parent of the inserted Attribute node.
- As an alternative to the URI argument on AddElement and AddAttribute, a
namespace declaration is created at an element with the AddNamespace method.
AddNamespace also lets you insert a namespace declaration that is not used by
an element nor any of its attributes.
For example, the following fragment:
%n = %doc:AddElement('a') %n:AddNamespace('x', 'y:z') %n:AddElement('x:b') %n:AddElement('x:c')
Creates the following document:
<a xmlns:x="y:z"> <x:b/> <x:c/> </a>
- When the AddSubtree method copies between different XmlDocs, it does not allow the source and target XmlDocs to have different Namespace property settings (doing so could require re-parsing names in some cases).
- The namespace axis is not allowed in an XPath expression. Without XPath access to a pointer to a namespace node, the namespace clearly cannot be changed nor deleted, so the URIs associated with nodes cannot be "changed out from under". You can obtain the information in a namespace declaration, however, using certain XmlDoc API methods (for example, the Uri property of an XmlNode).
Deleting nodes
The XmlDoc API subroutine used to delete individual nodes (and their descendants) from an XmlDoc is DeleteSubtree. An example is shown below.
If a node you delete was referenced by an XmlNode, the value of that XmlNode becomes Null. Similarly, if any deleted nodes were referenced by an item of an XmlNodelist, the value of that item of the XmlNodelist becomes Null.
If you need to “clean up” an XmlNodelist that refers to a deleted XmlDoc node, you can use the Difference function, as shown in the following example.
In the example, the XmlNodelist object (%nlis
) is cleaned up
(with Difference) to remove the second item from the
nodelist before referencing the nodelist items.
The reference to the nodelist items
uses relative XPath (the '@auth'
argument of the Value method invocation, selecting attributes named
auth
).
%nlis Object XmlNodelist %rlis Object XmlNodelist * Get nodelist for chapters, and * delete Dave's chapter from the XmlDoc: %nlis = %d:Nodes('/book/chapter') %rlis = %d:Nodes('/book/chapter[@auth="Dave"]') For %i From 1 to %rlis:Count %rlis:Item(%i):DeleteSubtree End For * Cleanup the chapter nodelist, show author of * remaining chapters, & display the document: %nlis = %nlis:Difference(%rlis) For %i From 1 To %nlis:Count Print 'Author:' And %nlis:Item(%i):Value('@auth') End For %d:Print ...
Namespace URI for XPath prefixes
It is important to realize that the URI associated with a prefix
in the XML document is controlled by the xmlns
namespace declarations in the document.
However, when a prefix is used in a name in an XPath argument to
an XmlDoc API method, the URI for that prefix must be established
so that the full XPath name (local part and URI namespace)
can be used to locate a document element.
This association of XPath prefixes to URIs is established using
the SelectionNamespace property.
The prefix names used in Xpath selection are independent of the prefix names used in the document serialization and deserialization. Since an XML document element prefix may be associated with multiple namespaces, or an element may have a namespace and no associated prefix, XPath prefixes stipulate the namespace that fully qualifies an element name in an XPath location step.
Transport: receiving and sending XML
The provision for receiving and sending XML is very simple:
- Receiving XML involves converting the information from the character,
marked-up form of an XML document into an XmlDoc;
this operation is called deserialization.
- The WebReceive function is designed to receive an XML document that has arrived as a web request.
- The ParseXml function of the HttpResponse class accomplishes this for HTTP clients.
- For other transport mechanisms, such as Model 204 MQ Series, the character-format XML document can be placed into a longstring, and the LoadXml function then places the information into an XmlDoc.
- Sending XML involves converting the information in an XmlDoc to a
character stream, including markup such as element tags;
this operation is called serialization.
- The WebSend subroutine is designed to send an XML document as a web response.
- The AddXml method of the HttpRequest class accomplishes this for HTTP clients.
- For other transport mechanisms, such as Model 204 MQ Series, the Serial function is used to place the serialized form into a Longstring, which can then be sent.
About encoding:
- When the internal representation of an XmlDoc is EBCDIC (prior to Sirius Mods 7.6), the deserialization methods reject a document if it contains an ISO-10646 (Unicode) character that cannot be represented in EBCDIC. When the internal representation of an XmlDoc is Unicode (Sirius Mods 7.6 and higher), the deserialization methods by default reject a document if it contains a Unicode character that is not translatable to EBCDIC. See Char and Reference for more information about characters in an XML document.
- The encodings that are accepted in the deserialization operations
are
UTF-8
andUTF-16
, andISO-8859-n
(where n is a digit from 1 to 9). Prior to Sirius Mods Version 7.6, all of theISO-8859-n
variants are treated asISO-8859-1
. As of Sirius Mods 7.6, the variants determine Ascii to Unicode conversions according to the specification of the individual variant. Note: These encoding names must be specified in uppercase letters. - When the document is serialized, the result is either EBCDIC or is in
the UTF-8 encoding.
Therefore,
the only values permitted to be set for the Encoding property
are
UTF-8
and the null string; in that, see the Usage Notes for more information about the character sets allowed in a serialized input XML document and the value ofencoding
in an XML declaration.
Strings and Unicode with the XmlDoc API
As of Sirius Mods version 7.6, XmlDocs are maintained in Unicode rather than EBCDIC; this is true for all string values, names, prefixes, and URIs. As a consequence, most of the arguments and results of the XmlDoc API methods that formerly were strings or longstrings are Unicode strings as of version 7.6.
This switch to Unicode requires little or no change to most existing XmlDoc API applications, however: XmlDoc API argument and result variables declared as String or Longstring are automatically converted from EBCDIC to Unicode by the Sirius Mods. For example, the EBCDIC character strings in the arguments in a statement like the following are automatically converted to Unicode:
%d:AddElement('name', 'value')
Similarly,
if the variable %str
, below, was declared as type String or
Longstring, then the Unicode result of the Value method is automatically
converted to EBCDIC when it is stored in %str
:
%str = %n:Value
The principal benefit of this switch to Unicode is conformance with the W3C XML standard, which defines “characters” in terms of Unicode characters (most of which are valid in XML documents). You can now store string values that are not translatable to EBCDIC — Sirius Mods 7.5 allows storage only of (most) non-null EBCDIC characters or of characters that translate to those EBCDIC characters.
The automatic EBCDIC/Unicode conversions described above will not cause request cancellations in requests that run successfully under Sirius Mods 7.5. But there are other changes to or effects on the XmlDoc API that are due to the switch to Unicode maintenance (the Sirius Mods Release 7.6 Notes and the individual method descriptions provide additional details):
- The workaround (InvalidChar method) for accommodating nulls and EBCDIC
characters that are not allowed by the XML standard is replaced by:
- The AllowNull property can let nulls be stored in an XmlDoc.
- A method argument (AllowUntranslatable) of the deserialization methods that lets you store Unicode characters that do not translate to EBCDIC. Such characters may be also stored directly by the Add* and Insert* methods of the XmlDoc API; these methods do not require a special argument. EBCDIC characters that do not translate to Unicode must be handled before they are passed to an XmlDoc update operation. For example, EBCDIC X'04' is the SEL (“Select”) control character. Since there is no “Select” control character in Unicode, there is no mapping between EBCDIC X'04' and any Unicode character. For this you might use the Untranslatable parameter of the EbcdicToUnicode function.
- If you have defined uninvertible translations (?? refid=ucdinv.),
the implicit translation of EBCDIC string arguments and results to Unicode
as of version 7.6 of the Sirius Mods will change the behavior of the
XmlDoc API methods compared to their operation in version 7.5.
For example, assume CCAIN establishes codepage 0037 as the base,
but it also uses the following UNICODE commands (?? refid=ucmd.)
to allow for the codepage 1047 square bracket characters:
UNICODE Table Standard Trans E=AD To U=005B UNICODE Table Standard Trans E=BD To U=005D
These UNICDOE commands cause uninvertible translations. For example, by the first command, EBCDIC X'AD' translates to U+005B, but by the definition of codepage 0037, U+005B translates to EBCDIC X'BA'. Consequently, you can add a X'AD' character to an XmlDoc, but if you display its value:
%nod:AddElement('leftSquare', 'AD':X) Print %nod:Value('leftSquare'):StringToHex
You get the following result:
BA
The Value method returns the Unicode character U+005B, which is translated implicitly to EBCDIC X'BA' as the string input for StringToHex.
In version 7.5, because XmlDoc strings are stored in EBCDIC, no implicit translation is performed, and the result of the above two statements is:
AD
- The Print subroutine is equipped to display the Unicode values that are stored in XmlDocs, even if the Unicode characters are not translatable to EBCDIC. If non-translatable Unicode characters are stored in XmlDoc Attribute or Element values, Print displays their XML hexadecimal character references. If non-translatable Unicode characters are stored in a context other than Element or Attribute (a name, Comment, or Pi), the Print CharacterEncodeAll option is required to display a character reference and avoid request cancellation.
- As described further in ?? refid=uniconv., the User Language Print
statement under Sirius Mods 7.6 does not cancel the request
if it is presented with a Unicode character that does not translate to EBCDIC.
If it encounters an untranslatable Unicode character, Print will display
an EBCDIC string that contains the character's hex encoding.
As an example, consider the direct printing of the output of Value.
Say the element node assigned to
%nodeY
contains the Unicode trademark character (U+2122), which does not translate to EBCDIC. The following statement succeeds because the Print statement can handle untranslatable Unicode characters:Print %nodeY:Value
The result under Sirius Mods 7.5 is a request cancellation. The result under Sirius Mods 7.6 is:
™
However, the following common operation using the StringToHex method with Value does not succeed:
Print %nodeY:Value:stringToHex
When StringToHex attempts to implicitly convert to EBCDIC the Unicode character passed to it by the Value function, the conversion fails because the character is not translatable to EBCDIC, and the request is cancelled. Such an implicit conversion, which simply uses the current Unicode translation tables, does not do character encoding.
To avoid a request cancellation here and view the Value result, you can use the UnicodeToUtf16 function to encode the Unicode character as a UTF-16 string for input to StringToHex:
Print %nodeY:Value:unicodeToUtf16:stringToHex
For more information about the characters that are valid in an XmlDoc API XML document, see ?? refid=isoebcd.
Using Longstrings or Unicode instead of Strings
The Unicode and Longstring datatypes, described in ?? refid=lstr., provides an atomic type that can contain a string longer than 255 bytes. The XmlDoc API methods, like all Janus SOAP User Language Interface methods, accept strings longer than 255 whenever they have a string argument or result, which is to say:
- Input values may exceed 255 bytes in length.
- Various XmlDoc API methods will return a string longer than 255 bytes, if indeed the result value exceeds 255 bytes.
The following subsections provide some guidelines to determine when
you 'must' use a longstring (or Unicode, as of Sirius Mods version 7.6)
%variable or context for a string argument or for
the result of a method in the XmlDoc API.
Since the server table requirements and the processing overhead
for Longstring or Unicode are just a little more than for a String Len
255
%variable, it is recommended that you use a Longstring or Unicode in the
XmlDoc API methods wherever you might be using a String Len 255
%variable.
Xml and Serial methods
You should use a Longstring or Unicode %variable to hold the result of the Xml or Serial methods — the total concatenated length of all markup and character content in a document (or subtree, for Serial) — which will most likely exceed 255 bytes. Thus, the first invocation of the Xml method below will never fail (for length reasons) but the second will usually cause a request cancellation:
%ls Longstring %ls = %doc:Serial %ss String Len 255 %ss = %doc:Serial
Value[Default] methods
Usually you should use a Longstring or Unicode %variable to hold the result of the Value or ValueDefault methods. For example, the first two invocations of the Value method below will succeed but the third will cause a request cancellation:
%ss String Len 255 %ls Longstring %doc:LoadXml('<top> <big>' With - $Lstr_Left('a', 300) With '</big> <little>' - With 'Less than 256 chars</little> </top>') %ls = %doc:Value('/top/big') %ss = %doc:Value('/top/little') %ss = %doc:Value('/top/big')
As noted above, the best approach here is to use Longstring or Unicode %variables
where you might use String Len 255
%variables.
Besides the Xml and Value methods, other XmlDoc API methods either cannot return a value longer than 255 bytes or, with typical XML documents, are unlikely to do so. If you have a namespace URI that exceeds 255 bytes, it may be necessary to use a Longstring or Unicode %variable.
For example, the first two invocations of the Uri method below will succeed, but the third will cause a request cancellation:
%ss String Len 255 %ls Longstring %doc:LoadXml('<top><a:inner xmlns:a="urn:' With - $Lstr_Left('big', 300, '_') With '"/></top>') %ss = %doc:URI('*') %ls = %doc:URI('*/*') %ss = %doc:URI('*/*')
As noted above, the easiest approach here is to use Longstring or Unicode
%variables where you might use String Len 255
%variables.
Conventions and terminology for XmlDoc API methds
In addition to those described in Notation conventions for methods, the following conventions are also used in the individual XmlDoc API method descriptions:
- Symbols used in the syntax include the following.
Usually, they represent method objects; in actual code, they may be
replaced by object variables
of the indicated class or by method invocations that return
such object variables:
- nr
- Denotes an abstract class (short for “node reference”) for methods that operate on a node and that can be used with either an XmlNode or an XmlDoc. If an XmlDoc, the node for the operation is the root node.
- doc
- Denotes an object of class XmlDoc.
- nod
- Denotes an object of class XmlNode.
- nlis
- Denotes an object of class XmlNodelist.
- Although the terms “XmlNode” and “node” are closely related, effort is made to distinguish them as necessary in the method descriptions. An XmlNode is an object that points to a node in an XmlDoc. Similarly, an XmlNodelist is an object that contains a set, or list, of XmlNodes selected from a particular XmlDoc. Strictly speaking, a “nodelist” does not exist, but the term is occasionally used as an abbreviation or generalization of XmlNodelist.
- Null objects, null strings, empty results
- A Null object is one that has been deleted or that has not been instantiated. A “null” string is a zero length string value. The text in the method descriptions distinguishes these two terms.
- Object-type arguments must not be Null, unless that argument explicitly allows Null. Hence, a Null argument typically causes a request cancellation. Currently, no XmlDoc API methods allow Null object arguments, and the “Request Cancellation Errors” section for each method does not include this condition.
- Some methods that have an XPath argument allow the result of the XPath expression to be the empty set of nodes; most, however, will cancel the request if this happens. Each method that has an XPath argument will either list the empty XPath result as a request cancellation error, or will explain the operation of the method when the XPath result is the empty nodeset.