Non-schema-based:XMLType tables and columns described in this chapter are not based on XML schema. You can, however, use the techniques and examples provided in this chapter regardless of which storage option you choose for your XMLType tables and columns. See Chapter 3, "Using Oracle XML DB" for further storage recommendations.

What Is XMLType?

Oracle9i Release 1 (9.0.1) introduced a new datatype, XMLType, to facilitate native handling of XML data in the database. The following summarizes XMLType:

XMLType can be used in PL/SQL stored procedures as parameters, return values, and variables.

XMLType can represent an XML document as an instance (of XMLType) in SQL.

XMLType has built-in member functions that operate on XML content. For example, you can use XMLType functions to create, extract, and index XML data stored in Oracle9i database.

Functionality is also available through a set of Application Program Interfaces (APIs) provided in PL/SQL and Java.

With XMLType and these capabilities, SQL developers can leverage the power of the relational database while working in the context of XML. Likewise, XML developers can leverage the power of XML standards while working in the context of a relational database.

XMLType datatype can be used as the datatype of columns in tables and views. Variables of XMLType can be used in PL/SQL stored procedures as parameters, return values, and so on. You can also use XMLType in SQL, PL/SQL, and Java (through JDBC).

Note:

In Oracle9i Release 1 (9.0.1), XMLType was only supported in the server in SQL, PL/SQL, and Java. In Oracle9i Release 2 (9.2), XMLType is also supported on the client side through SQL, Java, and protocols such as FTP and HTTP/WebDav.

A number of useful functions that operate on XML content are provided. Many of these are provided as both SQL and member functions of XMLType. For example, the extract() function extracts a specific node(s) from an XMLType instance.

You can use XMLType in SQL queries in the same way as any other user-defined datatypes in the system.

Benefits of the XMLType Data Type and API

The XMLType datatype and API provides significant advantages. It enables SQL operations on XML content, as well as XML operations on SQL content:

Versatile API.XMLType has a versatile API for application development, as it includes built-in functions, indexing support, navigation, and so on.

XMLType and SQL. You can use XMLType in SQL statements combined with other columns and datatypes. For example, you can query XMLType columns and join the result of the extraction with a relational column, and then Oracle can determine an optimal way to execute these queries.

Optimized evaluation using XMLType. XMLType is optimized to not materialize the XML data into a tree structure unless needed. Therefore when SQL selects XMLType instances inside queries, only a serialized form is exchanged across function boundaries. These are exploded into tree format only when operations such as extract() and existsNode() are performed. The internal structure of XMLType is also an optimized DOM-like tree structure.

Indexing. Oracle Text index has been enhanced to support XMLType columns. You can also create function-based indexes on existsNode() and extract() functions to speed up query evaluation.

When to Use XMLType

SQL queries on part of or the whole XML document: The functions existsNode() and extract() provide the necessary SQL query functions over XML documents.

Strong typing inside SQL statements and PL/SQL functions: Strong typing implies that you ensure that the values passed in are XML values and not any arbitrary text string.

XPath functionality provided by extract() and existsNode() functions: Note that XMLType uses the built-in C XML parser and processor and hence provides better performance and scalability when used inside the server.

Indexing on XPath searches on documents: XMLType has member functions that you can use to create function-based indexes to optimize searches.

To shield applications from storage models. Using XMLType instead of CLOBs or relational storage allows applications to gracefully move to various storage alternatives later without affecting any of the query or DML statements in the application.

To prepare for future optimizations. New XML functionality will support XMLType. Since Oracle9i database is natively aware that XMLType can store XML data, better optimizations and indexing techniques can be done. By writing applications to use XMLType, these optimizations and enhancements can be easily achieved and preserved in future releases without your needing to rewrite applications.

Storing XMLType Data in Oracle XML DB

XMLType data can be stored in two ways or a combination thereof:

In Large Objects (LOBs). LOB storage maintains content accuracy to the original XML (whitespaces and all). Here the XML documents are stored composed as whole documents like files. In this release, for non-schema-based storage, XMLType offers a CLOB storage option. In future releases, Oracle may provide other storage options, such as BLOBs, NCLOBS, and so on. You can also create a CLOB-based storage for XML schema-based storage.

When you create an XMLType column without any XML schema specification, a hidden CLOB column is automatically created to store the XML data. The XMLType column itself becomes a virtual column over this hidden CLOB column. It is not possible to directly access the CLOB column; however, you can set the storage characteristics for the column using the XMLType storage clause.

Unstructured content declared in the schema. For example, content="mixed" or <any> declarations.

Undeclared data in instance documents, such as processing instructions, comments, and namespace declarations.

Support for basic XML datatypes not available in SQL (Boolean, QName, and so on).

Support for XML constraints (facets) not supported directly by SQL, such as enumerated lists.

Native XMLType instances contain hidden columns that store this extra information that does not quite fit in the SQL object model. This information can be accessed through APIs in SQL or Java, using member functions, such as extractNode().

Changing XMLType storage from structured storage to LOB, or vice versa, is possible using database IMPORT and EXPORT. Your application code does not have to change. You can then change XML storage options when tuning your application, since each storage option has its own benefits.

XMLType Member Functions

Oracle9i Release 1 (9.0.1) introduced several SQL functions and XMLType member functions that operate on XMLType values. Oracle9i Release 2 (9.2) has expanded functionality. It provides several new SQL functions and XMLType member functions.

All XMLType functions use the built-in C parser and processor to parse XML data, validate it, and apply XPath expressions on it. They also use an optimized in-memory DOM tree for processing, such as extracting XML documents or fragments.

How to Use the XMLType API

You can use the XMLType API to create tables and columns. The createXML() static function of the XMLType API can be used to create XMLType instances for insertion. By storing your XML documents as XMLType, XML content can be readily searched using standard SQL queries.

This example creates an XMLType instance from a string literal. The input to createXML() can be any expression that returns a VARCHAR2 or CLOB. createXML() also checks that the input XML is well-formed.

Using XMLType in an SQL Statement

The following simple SELECT statement shows how you can use XMLType in an SQL statement:

This example created an XMLType instance from a string literal and updates column warehouse_spec with the new value.

Note:

Any triggers would get fired on the UPDATE statement You can see and modify the XML value inside the triggers.

Deleting a Row Containing an XMLType Column

Deleting a row containing an XMLType column is no different from deleting a row containing any other datatype.

Example 4-8 Deleting an XMLType Column Row

You can use extract() and existsNode() functions to identify rows to delete as well. For example to delete all warehouse rows for which the warehouse building is leased, you can write a statement such as:

Select or Extract a Particular XMLType Instance

You can select out the XMLType instance from the column. XMLType also offers a choice of member functions, such as extract() and existsNode(), to extract a particular node and to check to see if a node exists respectively. See the table of XMLType member functions in Oracle9i XML API Reference - XDK and Oracle XML DB.

You can Define an Oracle Text Index

You can define an Oracle Text index on XMLType columns. This enables you to use CONTAINS, HASPATH, INPATH, and other text operators on the column. All the Oracle Text operators and index functions that operate on LOB columns also work on XMLType columns.

You Can Define XPath Index, CTXXPATH

In this release, a new Oracle Text index type, CTXXPATH is introduced. This helps existsNode() implement indexing and optimizes the evaluation of existsNode() in a predicate.

Specifying Storage Characteristics on XMLType Columns

XML data in an XMLType column can be stored as a CLOB column. Hence you can also specify LOB storage characteristics for that column. In example, "Creating XMLType: Creating XMLType Columns", the warehouse_spec column is an XMLType column.

Example 4-9 Specifying Storage When Creating an XMLType Table

You can specify storage characteristics on this column when creating the table as follows:

To change the storage characteristics of LOB column a in foo_tab, you can use the following statement:

ALTER TABLE foo_tab MODIFY LOB (a.xmldata) (storage (next 5K) cache);

XMLDATA identifies the internal storage column. In the case of CLOB-based storage this corresponds to the CLOB column. The same holds for XML schema-based storage. You can use XMLDATA to explore structured storage and modify the values.

Note:

In this release, the XMLDATA attribute helps access the XMLType's internal storage columns so that you can specify storage characteristics, constraints, and so on directly on that column.

You can use the XMLDATA attribute in constraints and indexes, in addition to storage clauses.

You can also define check constraints on XMLType columns. Other default values are not supported on this datatype.

Manipulating XML Data in XMLType Columns/Tables

Since XMLType is a user-defined data type with functions defined on it, you can invoke functions on XMLType and obtain results. You can use XMLType wherever you use a user-defined type, including for table columns, views, trigger bodies, and type definitions.

You can perform the following manipulations or Data Manipulation Language (DML) on XML data in XMLType columns and tables:

Inserting XML Data into XMLType Columns/Tables

XMLType columns can only store well-formed XML documents. Fragments and other non-well-formed XML cannot be stored in XMLType columns.

Using INSERT Statements

To use the INSERT statement to insert XML data into XMLType, you need to first create XML documents to perform the insert with. You can create the insertable XML documents as follows:

By using XMLType constructors. This can be done in SQL, PL/SQL, and Java.

By using SQL functions like XMLElement(), XMLConcat(), and XMLAGG(). This can be done in SQL, PL/SQL, and Java.

Example 4-14 Inserting XML Data Using createXML() with CLOB

The following examples use INSERT...SELECT and the XMLType constructor to first create an XML document and then insert the document into the XMLType columns. Consider table po_clob_tab that contains a CLOB, poClob, for storing an XML document:

Example 4-17 Inserting XML Data Using XMLElement()

This example inserts a purchase order into table po_xml_tab by generating it using the XMLElement() SQL function. Assume that the purchase order is an object view that contains a purchase order object. The whole definition of the purchase order view is given in "DBMS_XMLGEN: Generating a Purchase Order from the Database in XML Format".

SQL Functions for Manipulating XML data

SQL functions such as existsNode(), extract(), XMLTransform(), and updateXML() operate on XML data inside SQL. XMLType datatype supports most of these as member functions. You can use either the selfish style of invocation or the SQL functions.

Selecting XML Data

You can select XMLType data using PL/SQL or Java. You can also use the getClobVal(), getStringVal(), or getNumberVal() functions to retrieve XML as a CLOB, VARCHAR, or NUMBER, respectively.

Querying XML Data

You can query XMLType data and extract portions of it using the existsNode() and extract() functions. Both these functions use a subset of the W3C XPath recommendation to navigate the document.

Using XPath Expressions for Searching XML Documents

XPath is a W3C recommendation for navigating XML documents. XPath models the XML document as a tree of nodes. It provides a rich set of operations to "walk" the tree and to apply predicates and node test functions. Applying an XPath expression to an XML document can result in a set of nodes. For instance, /PO/PONO selects out all "PONO" child elements under the "PO" root element of the document.

Table 4-2 Some Common XPath Constructs

Denotes the root of the tree in an XPath expression. For example, /PO refers to the child of the root node whose name is "PO".

"/"

Also used as a path separator to identify the children node of any given node. For example, /PO/PNAME identifies the purchase order name element, a child of the root element.

"//"

Used to identify all descendants of the current node. For example, PO//ZIP matches any zip code element under the "PO" element.

"*"

Used as a wildcard to match any child node. For example, /PO/*/STREET matches any street element that is a grandchild of the "PO" element.

[ ]

Used to denote predicate expressions. XPath supports a rich list of binary operators such as OR, AND, and NOT. For example, /PO[PONO=20 and PNAME="PO_2"]/SHIPADDR select out the shipping address element of all purchase orders whose purchase order number is 20 and whose purchase order name is "PO_2". [ ] is also used for denoting an index into a list. For example, /PO/PONO[2] identifies the second purchase order number element under the "PO" root element.

The XPath must identify a single or a set of element, text, or attribute nodes. The result of the XPath cannot be a boolean expression.

Querying XML Data Using XMLType Member Functions

You can select XMLType data through PL/SQL, OCI, or Java. You can also use the getClobVal(), getStringVal(), or getNumberVal() functions to retrieve the XML as a CLOB, VARCHAR or a number, respectively.

Example 4-19 Retrieving an XML Document as a CLOB Using getClobVal() and existsNode()

This example shows how to select an XMLType column using getClobVal() and existsNode():

Figure 4-2 existsNode() Syntax

existsNode() function on XMLType checks if the given XPath evaluation results in at least a single XML element or text node. If so, it returns the numeric value 1, otherwise, it returns a 0. Namespace can be used to identify the mapping of prefix(es) specified in the XPath_string to the corresponding namespace(s).

The extract() function is similar to the existsNode() function. It applies a VARCHAR2XPath string with an optional namespace parameter and returns an XMLType instance containing an XML fragment. The syntax is described in Figure 4-3 and as follows:

Figure 4-3 extract() Syntax

extract() on XMLType extracts the node or a set of nodes from the document identified by the XPath expression. The extracted nodes can be elements, attributes, or text nodes. When extracted out, all text nodes are collapsed into a single text node value. Namespace can be used to supply namespace information for prefixes in the XPath string.

The XMLType resulting from applying an XPath through extract() need not be a well-formed XML document but can contain a set of nodes or simple scalar data in some cases. You can use the getStringVal() or getNumberVal() methods on XMLType to extract this scalar data.

For example, the XPath expression /PO/PNAME identifies the PNAME element inside the XML document shown previously. The expression /PO/PNAME/text(), on the other hand, refers to the text node of the PNAME element.

Note:

The latter is still considered an XMLType. In other words, extract(poDoc,'/PO/PNAME/text()') still returns an XMLtype instance although the instance may actually contain only text. You can use getStringVal() to get the text value out as a VARCHAR2 result.

Use text() node test function to identify text nodes in elements before using the getStringVal() or getNumberVal() to convert them to SQL data. Not having the text() node would produce an XML fragment.

For example, XPath expressions:

/PO/PNAME identifies the fragment <PNAME>PO_1</PNAME>

/PO/PNAME/text() identifies the text value "PO_1"

You can use the index mechanism to identify individual elements in case of repeated elements in an XML document. For example, if you have an XML document such as:

<PO>
<PONO>100</PONO>
<PONO>200</PONO>
</PO>

you can use:

//PONO[1] to identify the first "PONO" element (with value 100).

//PONO[2] to identify the second "PONO" element (with value 200).

The result of extract() is always an XMLType. If applying the XPath produces an empty set, then extract() returns a NULL value.

Hence, extract() member function can be used in a number of ways, including the following:

Extracting numerical values on which function-based indexes can be created to speed up processing

Extracting collection expressions to be used in the FROM clause of SQL statements

Extracting fragments to be later aggregated to produce different documents

Example 4-22 Using extract() to Extract the Value of a Node

This example extracts the value of node, /Warehouse/Docks, of column, warehouse_spec in table oe.warehouses:

extractValue() Function

The extractValue() function takes as arguments an XMLType instance and an XPath expression. It returns a scalar value corresponding to the result of the XPath evaluation on the XMLType instance. extractValue() syntax is also described in Figure 4-4.

XML schema-based documents. For documents based on XML schema, if Oracle9i can infer the type of the return value, then a scalar value of the appropriate type is returned. Otherwise, the result is of type VARCHAR2.

Non- schema-based documents. For documents not based on XML schemas, the return type is always VARCHAR2.

extractValue() tries to infer the proper return type from the XML schema of the document. If the XMLType is non- schema-based or the proper return type cannot be determined, Oracle XML DB returns a VARCHAR2.

Figure 4-4 extractValue() Syntax

A Shortcut Function

extractValue() permits you to extract the desired value more easily than when using the equivalent extract function. It is an ease-of-use and shortcut function. So instead of using:

extract(x,'path/text()').get(string|num)val()

you can replace extract().getStringVal() or extract().getnumberval() with extractValue() as follows:

extractValue(x, 'path/text()')

With extractValue() you can leave off the text(), but ONLY if the node pointed to by the 'path' part has only one child and that child is a text node. Otherwise, an error is thrown.

extractValue() syntax is the same as extract().

extractValue() Characteristics

extractValue() has the following characteristics:

It always returns only scalar content, such as NUMBER...VARCHAR2, and so on.

It cannot return XML nodes or mixed content. It raises an error at compile or run time if it gets XML nodes as the result.

It always returns VARCHAR2 by default. If the node's value is bigger than 4K, a runtime error would occur.

In the presence of XML schema information, at compile time, extractValue() can automatically return the appropriate datatype based on the XML schema information, if it can detect so at compile time of the query. For instance, if the XML schema information for the path /PO/POID indicates that this is a numerical value, then extractValue() returns a NUMBER.

If the XPath identifies a node, it automatically gets the scalar content from its text child. The node must have exactly one text child. For example:

extractValue(xmlinstance, '/PO/PNAME')

extracts out the text child of PNAME. This is equivalent to:

extract(xmlinstance, '/PO/PNAME/text()').getstringval()

Example 4-23 Extracting the Scalar Value of an XML Fragment Using extractValue()

The following example takes as input the same arguments as the example for extract () Function. Instead of returning an XML fragment, as extract() does, it returns the scalar value of the XML fragment:

Here is an SQL example assuming that the XML described in the previous example is present in the po_xml_tab:

INSERT INTO po_rel_tab
SELECT p.poDoc.extract('/PO/PONO/text()').getnumberval() as pono,
p.poDoc.extract('/PO/PNAME/text()').getstringval() as pname,
-- get the customer id corresponding to the customer name
( SELECT c.custid
FROM cust_tab c
WHERE c.custname = p.poDoc.extract('/PO/CUSTOMER/@CUSTNAME').getstringval()
) as custid,
p.poDoc.extract('/PO/SHIPADDR/STREET/text()').getstringval() as shipstreetr,
p.poDoc.extract('//CITY/text()').getstringval() as shipcity,
p.poDoc.extract('//ZIP/text()').getstringval() as shipzip
FROM po_xml_tab p;

This SQL statement extracts the purchase order name "PNAME" from purchase order element PO, from all XML documents containing a shipping address with a purchase order number of 300, and a customer name "CUSTNAME" containing the string "John".

Example 4-30 Extracting Fragments from XMLType Using extract()

extract() member function extracts nodes identified by the XPath expression and returns an XMLType containing the fragment. Here, the result of the traversal may be a set of nodes, a singleton node, or a text value. You can check if the result is a fragment by using the isFragment() function on the XMLType. For example:

You cannot insert fragments into XMLType columns. You can use SYS_XMLGEN() to convert a fragment into a well-formed document by adding an enclosing tag. See "SYS_XMLGEN() Function". You can, however, query further on the fragment using the various XMLType functions.

The previous SQL statement returns 0, since the extraction /PO/SHIPADDR/STATE returns a singleton well-formed node which is not a fragment.

On the other hand, an XPath such as /PO/SHIPADDR/STATE/text() is considered a fragment, since it is not a well-formed XML document.

Updating XML Instances and Data in Tables and Columns

With CLOB-based storage, in this release, an update effectively replaces the whole document. Use the SQL UPDATE statement to update the whole XML document. The right hand side of the UPDATE's SET clause must be an XMLType instance. This can be created using the SQL functions and XML constructors that return an XML instance, or using the PL/SQL DOM APIs for XMLType or Java DOM API, that change and bind existing XML instances.

updateXML() SQL Function

updateXML() function takes in a source XMLType instance, and a set of XPath value pairs. It returns a new XML instance consisting of the original XMLType instance with appropriate XML nodes updated with the given values. The optional namespace parameter specifies the namespace mapping of prefix(es) in the XPath parameters.

updateXML() can be used to update, replace elements, attributes and other nodes with new values. They cannot be directly used to insert new nodes or delete existing ones. The containing parent element should be updated with the new values instead.

To generate a new document with Joe's salary updated to 100,000, update the Name of Jack to Jackson, and modify the Employee element for 217, to remove the salary element. You can write a query such as:

Example 4-36 Creating Views Using updateXML()

ensures that users selecting from view, new_emp_view, do not see the SALARY field for any employee.

Optimization of updateXML()

In most cases, updateXML() materializes the whole input XML document in memory and updates the values. However, it is optimized for UPDATE statements on XML schema-based object-relationally stored XMLType tables and columns so that the function updates the value directly in the column.

could get rewritten (if the rewrite rules are satisfied) to an UPDATE of the custname column directly:

UPDATE po_xml_tab p
SET p.xmldata.CUSTNAME = 'John';

updateXML() and NULL Values

If you update an XML element to null, Oracle removes the attributes and children of the element, and the element becomes empty. The type and namespace properties of the element are retained. A NULL value for an element update is equivalent to setting the element to empty.

If you update the text node of an element to null, Oracle removes the text value of the element, and the element itself remains but is empty. For example, if you update node, '/empno/text()' with a NULL value, the text values for the empno element are removed and the empno element becomes empty.

Setting an attribute to NULL, similarly sets the value of the attribute to the empty string.

You cannot use updateXML() to remove, add, or delete a particular element or an attribute. You have to update the containing element with a new value.

Note:

Setting 'empno' to NULL has the same effect as setting 'empno/text()' to NULL, if empno is a simple scalar element with no attributes.

Updating the Same XML Node More Than Once

You can update the same XML node more than once in the updateXML() statement. For example, you can update both /EMP[EMPNO=217] and /EMP[EMPNAME="Jane"]/EMPNO, where the first XPath identifies the EMPNO node containing it as well. The order of updates is determined by the order of the XPath expressions in left-to-right order. Each successive XPath works on the result of the previous XPath update.

XMLTransform() Function

TheXMLTransform() function takes in an XMLType instance and an XSLT stylesheet. It applies the stylesheet to the XML document and returns a transformed XML instance. See Figure 4-5.

This example is only an illustration. You can use the XMLType value to perform useful operations inside the trigger, such as validation of business logic or rules that the XML document should conform to, auditing, and so on.

Indexing XMLType Columns

You can create the following indexes when using XMLType. Indexing speeds up query evaluation.

Creating Function-Based Indexes on XMLType Columns

You can speed up by queries by building function-based indexes on existsNode() or those portions of the XML document that use extract().

The SQL query uses this function-based index, to evaluate the predicate instead of parsing the XML document row by row, and evaluating the XPath expression.

Example 4-41 Creating a Function-Based index on an existsNode() Function

You can also create bitmapped function-based indexes to speed up the evaluation of the operators. existsNode() is suitable, since it returns a value of 1 or 0 depending on whether the XPath is satisfied in the XML document or not.

For example, to speed up a query that searches whether the XML document contains an element called Shippingaddress (SHIPADDR) at any level:

Creating Oracle Text Indexes on XMLType Columns

Oracle Text index works on CLOB and VARCHAR columns. It has been extended in Oracle9i to also work on XMLType columns. The default behavior of Oracle Text index is to automatically create XML sections, when defined over XMLType columns. Oracle Text also provides the CONTAINS operator which has been extended to support XPath.

In general, Oracle Text indexes can be created using the CREATE INDEX SQL statement with the INDEXTYPE specified as for other CLOB or VARCHAR columns. Oracle Text indexes on XMLType columns, however, are created as function-based indexes.

Example 4-42 Creating an Oracle Text Index

You can also perform Oracle Text operations such as CONTAINS and SCORE. on XMLType columns. In Oracle9i Release (9.0.1), the CONTAINS operator was enhanced to support XPath using two new operators, INPATH and HASPATH:

INPATH checks if the given word appears within the path specified.

HASPATH checks if the given XPath is present in the XML document.

Example 4-43 Searching XML Data Using HASPATH

QUERY_REWRITE PRIVILEGE Is No Longer Needed

In Oracle9i Release (9.0.1), to create and use Oracle Text index in queries, in addition to having the privileges for creating indexes and for creating Oracle Text indexes, you also needed privileges and settings for creating function-based indexes:

QUERY_REWRITE privilege. You must have this privilege granted to create text indexes on XMLType columns in your own schema.

GLOBAL_QUERY_REWRITE privilege. If you need to create Oracle Text indexes on XMLType columns in other schemas or on tables residing in other schemas, you must have this privilege granted.

Oracle Text index uses the PATH_SECTION_GROUP as the default section group when indexing XMLType columns. This default can be overridden during Oracle Text index creation.

With this release, you no longer need the additional QUERY_REWRITE privileges when creating Oracle Text indexes.

The QUERY_REWRITE_INTEGRITY and QUERY_REWRITE_ENABLED session settings are no longer needed to create Oracle Text or other function-based indexes on XMLType columns.

Creating XPath Indexes on XMLType Columns: CTXXPATH Index

existsNode() SQL function, unlike the CONTAINS operator, cannot use Oracle Text indexes to speed up its evaluation. To improve the performance of XPath searches in existsNode(), this release introduces a new index type, CTXXPATH.

CTXXPATH index is a new indextype provided by Oracle Text. It is designed to serve as a primary filter for existsNode() processing, that is, it produces a superset of the results that would be produced by the existNode() function. The existsNode() functional implementation is then applied on the results to return the correct set of rows.

Both the function-based indexes and Oracle Text indexes support navigation. Thus you can use the Oracle Text index as a primary filter, to filter out all documents that potentially match the criterion, efficiently, and then apply secondary filters such as existsNode() or extract() operations on the remainder of the XML documents.