Application Programming Interface for XML DBMS: design and implementation proposal

Maria Rekouts

Institute for System Programming of Russian Academy of Sciences [email protected] Ph.D. Advisor A.N. Tomilin

Abstract Navigational API and present our implementation proposal of Navigational API. As XML becomes ubiquitous, there are a growing number of applications that uti- 2 The Sedna API lize it. Most of such applications working with some kinds of XML storages, in par- The API must provide programmatic access to XML ticular with Native XML , need from some programming language. We chose to perform navigation over XML data re- Java for this language because of the number of rea- trieved from the . The Application sons: mostly because of its flexibility and opportune Programming Interface with efficient navi- mechanisms such as garbage collection, also because gational facilities, that XML DBMS must of its popularity, some of the reasons we will discuss provide these applications with, is still un- below. Using the API, application written in the der discussion among XML DBMS develop- Java programming language can establish a connec- ers. In this paper we present design and tion with DBMS server, manage user sessions, man- implementation of XML DBMS Application age transactions, pass query as a string to server for Programming Interface that provides effi- execution, get the result and navigate over the result cient navigational facilities. of a query. We do not propose exact list of all API interfaces 1 Introduction and methods but below we consider API functions in more detail. When we say object of an interface XML [4] is finding its way into applications beyond we mean an object of a class that implements that those that traditionally utilize markup languages. interface. In particular, XML is becoming popular as a data interchange notation for database-oriented applica- 2.1 Establishing a connection tions. On the other hand the need to process and store XML has prompted researches and develop- DatabaseManager interface is an entry point. The ap- ers to create Native XML DBMS (NXD). Currently, plication starts its work with DBMS by calling static there are about 20 different native XML DBMS on method getConnection of the DatabaseManager inter- the market: commercial and open source. Most of face. them are quite raw. And some of the main mech- The API defines the Connection interface to anisms are still under discussion. API (Application represent a connection to a DBMS server. The Programming Interface), that NXD should provide Connection can also be considered as a user session. applications with, is one of those mechanisms. In Using static method getConnection(String DB- this paper we discuss design and implementation as- Name, String user, String password) of the pects of the API for a Native XML Database named DatabaseManager interface, application connects Sedna [8]. to the DBMS server and the server performs We have marked out a number of basic notions authorization with the parameters specified. If that do not depend on the and com- authorization succeeds the object of Connection mon to databases of different kinds. While devel- interface is returned. When finishing its work with oping the design we could not pass over relational DBMS application can break the connection using and object-oriented databases APIs, and in partic- close() method of a Connection interface. ular much was borrowed from the JDBC API. But in our paper the Navigational API, that is a subin- 2.2 Managing Transaction terface of XML DBMS API, is of greater interest. Ones a connection has been established, an appli- In this paper we focus on design of XML DBMS cation using the API can execute queries and up- Proceedings of the Spring Young Researcher’s Collo- dates against the DBMS server in defined trans- quium On Database and Information Systems SYR- action boundaries. Connection consists of transac- CoDIS, St.-Petersburg, Russia, 2004 tions, which are held one after another. Sedna API allows specifying transaction attributes by provid- in the Java can execute SQL statements and retrieve ing methods in the Connection interface: begin(), results. commit(), rollback() and createStatement(). To navigate over retrieved data application uses the ResultSet interface of the JDBC API. ResultSet 2.3 Managing Statements objects can have different functionality and charac- teristics. These characteristics are result set type, To execute XQuery statements and to retrieve result set concurrency and cursor holdability. The results application can use Statement inter- type of a Result Set object determines the level of face. createStatement() of a Connection in- its functionality in two main areas: (1) the way in terface is used to get object of the Statement which the cursor can be moved and (2) how concur- interface. Statement interface provides two rent changes made to the underlying data source are methods for executing XQuery queries: reflected by the ResultSet object. We consider only executeQueryLite and executeQueryHeavy. the first item in this section because it is relational executeQueryLite(String query) is used to get data model specific. the result in a serialized form (as a String). The ResultSet object is most often created as the executeQueryHeavy(String query) returns an object result of executing SQL statement. A ResultSet ob- of a Sequence interface as a result. Sequence ject maintains a cursor, which points to its current represents the result of XQuery query evaluation. row of data. When a ResultSet object is first cre- It provides navigational facilities over XML data ated, the cursor is positioned before the first row. and its mechanisms we will consider properly. The following methods can be used to move the cur- sor: 2.4 Navigational API • next()— moves the cursor forward one row, Today most applications that utilize XML data stored in XML DBMS need to be provided with easy • previous()– moves the cursor backwards one and versatile navigational facilities over that XML row, data. That is, XML DBMS API must include Nav- igational API. Such an API must allow the applica- • first()– moves the cursor to the first row in tion to navigate over XML data that was retrieved the ResultSet object, as a result of a query evaluation. Today Document Object Model (DOM) [1] is one • last()– moves the cursor to the last row in the of the most popular APIs for navigation over XML ResultSet object, data. DOM is a prevailing W3Cs proposal that is a • absolute(int row)– positions the cursor on the platform- and language-neutral interface that allows row-th row of the result set object. programs and scripts to dynamically access and up- date the content, structure of documents. Because After the cursor is set to the row required the val- of its prevalence it is also often considered as an in- ues of the column can be retrieved. The ResultSet terface for navigation over XML data retrieved from interface provides methods for retrieving the values XML database. But in our API proposal we do not of the columns from the row where the cursor is cur- use DOM because of the following reasons: first, it rently positioned. Two getter methods exist for each does not support data types of the XML Schema. JDBC type: one that takes the column index as its Second, it is designed to model XML documents, first parameter and one that takes the column name but not the result of evaluation of XQuery expres- or label. sion (this we discuss in 2.4.2 of this paper). From this short JDBC review we can conclude We believed, that the ways of navigation over that the navigation over relational data is completely some data (or the Navigational API functionality) simple because of its flat structure. First, you po- are determined mostly by the data model of those sition a cursor at the row required; second, you re- data. Thus, the Sedna XML DBMS API must pro- trieve a value from the column specified. In addi- vide functionality for navigation over XML data that tion, we take into account the fact that in up-to- rests upon XML Data Model. So, Navigational API date relational DBMS the length of the row is often is the part of the whole XML DBMS API that rad- restricted by the length of the server physical data ically differs from API for DBMS of another kind. pages. Thus, such navigation is easy to implement as Its design demands a new approach. every item of the ResultSet object – the row – need In this section we will discuss our proposal for not to be divided into parts and may be processed navigational API over XML data. But before that, as one unit of data. let us consider the issue in case of relational data in order to explore that experience for our goals. 2.4.2 Navigation over XML data

2.4.1 Navigation over relational data using In this section we consider the issue for the XML the JDBC API data. Here we fully rely on the XQuery 1.0 and XPath 2.0 Data Model [14]. The JDBC API [7] provides programmatic access The Navigational API of the Sedna XML DBMS to relational data from the Java programming lan- must implement the notions and concepts of the guage. Using the JDBC API, applications written XQuery 1.0 and Xpath 2.0 Data Model. In this Sequence QName Type interface describes one of the seven node kinds: next() document, element, attribute, text, namespace, pro-

getItem() cessing instruction, and comment. getType() When the type of item has been determined a Item ItemType node or an atomic value can be retrieved using

asNode() asAtom() asNode() and asAtom() methods. asNode() returns an object of the Node interface, asAtom() returns Node Atom NodeType AtomType an object of the Atom iterface. accesor-functions getType() getValue() Atom interface represents an atomic value. The ‘document’ XML Schema Types ‘element’ object of Atom class encapsulates the AtomType ‘attribute’ field that describes the type of the atomic value, and ‘text’ ‘namespace’ the value. ‘processing-instruction’ ‘comment’ In order for applications to be able to operate on instances of the data model, the model must expose Figure 1: Interrelation between the interfaces properties of the items it contains. The XQuery 1.0 and XPath 2.0 Data Model does this by defining section we consider the data model and present the a family of accessor functions. We consider acces- following interfaces that implement its notions and sors as a mechanism for navigation over XML data concepts: Sequence, Item, Node, Atom, ItemType, and associate a corresponding method in the Naviga- AtomType, NodeType and QName. We also con- tional API with every accessor. In XQuery 1.0 and sider node accessors as a mechanism for navigation. XPath 2.0 Data Model a set of accessors is defined Figure 1 shows the interrelation between the inter- on all seven kinds of Nodes. faces. Thus, in the Sedna Navigational API we define a According to [14] the value of an XQuery query Node interface to represent the node as it is defined expression is a sequence of zero or more items. An in [14]. The Node class encapsulates its type and item is either a node or an atomic value. A node provides methods that implement accessors accord- is one of seven node kinds: document, element, at- ing to this Node type. tribute, text, namespace, processing instruction, and Below we give an overview of the methods of Node comment. An atomic value encapsulates an XML class that implements accessors with some explana- Schema atomic type and a corresponding value of tions. When we use the term QName we mean the that type. A sequence is an ordered collection of QName class of the API that encapsulates the pair nodes, atomic values, or any mixture of nodes and of values consisting of a namespace URI and a local atomic values. A sequence cannot be a member of name. Listing all the accessors with their behavior a sequence. A single item appearing on its own is for every kind of nodes is out of this paper size. Our modeled as a sequence containing one item. proposal fully relies on [14] and all the details can Thus, turning back to our Sedna XML DBMS be found there. API, calling executeQueryHeavy method of a State- • base-uri returns an object of the Sequence ment interface produces the object of a Sequence class containing zero or one reference. Doc- interface. ument, element, and processing-instruction The Sequence interface represents the sequence nodes have a base-uri property. The base-uri as it is defined above. Similar to the JDBC API of all other node types is the empty sequence navigation over the sequence can be of two kinds: (an object of the Sequence class containing zero first, you can iterate over sequence items; second, items). If the base-uri property of a document, you can navigate over the Item itself. element, or processing-instruction node is non- For iterating over items of the sequence method empty, its value is returned. If the accessor is next() of the Sequence interface is provided. Next() called on a node that does not have a base-uri returns false if the sequence has finished. If true property, or whose base-uri property is empty, is returned the current item can be accessed using the base-uri of that node’s parent is returned. method getItem() that returns the object of the Item If the node has no parent, the empty sequence interface and navigation over this item can be pro- is returned. cessed. Item interface represents the item of a sequence as • node-kind - returns a string value identifying the it was defined above. It is a superinterface for Atom kind of node on which the accessor was called. and Node interfaces. It provides methods getType() One of the following values is returned: and isNode() that allows to determine whether the – current item is a node or an atomic value. Method ”document” for document nodes. isNode() returns true if the current item is a Node – ”element” for element nodes. and false if it is an Atom. Method getType() returns – ”attribute” for attribute nodes. an object of an ItemType class. – ”text” for text nodes. ItemType interface is a superinterface for Atom- Type and NodeType interfaces. An object of – ”namespace” for namespace nodes. the AtomType interface describes one of the XML – ”processing-instruction” for processing in- Schema atomic types [13]. An object of the Node- struction nodes. – ”comment” for comment nodes. In this section we have presented our proposal of Navigational API for XML data. Because of the • node-name returns a sequence of zero or one informality of our presentation some points could QNames. remain unclear, and so in the next section we give an illustrative example of the application program that – For element and attribute nodes node- uses Sedna XML DBMS API. The example will also name returns the qualified name of the el- be a material for discussion of the implementation ement or attribute. of the API that is the second part of our paper. – For processing-instructions nodes, node- name returns a QName with the process- 3 Example Program ing instruction target name in the local- name and no namespace URI. In this section we provide the example of application program that uses Sedna API to access the DBMS. – For namespace nodes, node-name returns Suppose there are documents named persons and an empty sequence. pets in the database. • parent returns a sequence containing zero or persons: one nodes. For nodes that have a parent, parent returns the parent node. For all other nodes, it returns the empty sequence. If the return John value is not the empty sequence, it will always Joe be either an element node or a document node. • string-value - every node has a string value; the way in which the string value of a node Mike is computed is different for each kind of node and is specified in the [14]. The string value of an atomic value is computed by casting it to a Tomas string. • typed-value for element nodes and attribute Mark nodes returns the typed value of a node, which Mark is a sequence of zero or more atomic values derived from the string value of the node and nodes type in a way that is specified in [14]. Samuel • type - returns the name of the type of the node (as a string) if it has one. If the type is anony- mous, or if no type information exists, the name A person can contain an information about its returned is no-type. For text nodes type returns nick: 1) as an attribute nick of element name 2) as untypedAtomic. For other nodes kinds, it re- an element nick. turns an empty string. pets:

• children - returns a sequence containing zero or more nodes. For document and element nodes, Tom it returns the nodes that are the children of that Sam node in document order. It returns the empty sequence for document and element nodes that have no children. If children exist, they will al- The example application has to retrieve all the ways consist exclusively of element, processing- persons and pets data, determine the nick of every instruction, comment, and text nodes. At- person if there are any and the nick of every pet and tribute, namespace, and document nodes can prints out the equal nicks. That is, as a result of its never appear as children. For all other nodes, work application prints out the persons nicks that it always returns the empty sequence. are pet names.

• attributes - returns a sequence containing zero import ru.ispras.sedna.driver.*; or more attribute nodes. For element nodes, these are the attributes of the node. For all String comp = computerName; other nodes, it always returns the empty se- String dbName = xmark; quence. String login = user; String password = pasw; • namespaces - returns a sequence containing zero or more namespace nodes. For element nodes, Connection con = DatabaseManager. these are the namespaces of the node. For all getConnection(comp, xmark, user, pasw); other nodes, it always returns the empty se- con.begin(); quence. Statement st1 = con.createStatement(); Statement st2 = con.createStatement(); the DBMS API. Our work is based on a client-server architecture. Vector person_nicks = new Vector(); There are an XML database server and client appli- cations running on the same computer or on different Sequence seq1 = computers in LAN. Client applications use driver to st1.executeQuery(document(\person\)/*/person); work with XML database server. Sequence seq2 = We assume that client applications are poorly re- st2.executeQuery(document(\pet\)/*/*/text()); sourced, particularly in memory resources. While working with DBMS client applications can obtain while(seq1.next()) big portions of data for navigation. As clients are { critical in their resources the situation when a por- Item item = seq1.getItem(); tion of data is too large for clients memory is quite if (item.isNode()) reasonable. Thus, our implementation must provide { some mechanisms that would allow poorly resourced Node node = item.asNode(); clients to navigate over large portions of XML data. Sequence children = node.children(); while(children.next()) 4.2 Caching Model { Item i = children.getItem(); Client applications navigation over big portions of if (i.isNode()) XML data that is not in memory at the client leads { to network and/or server bottlenecks. Such bottle- Node child = i.asNode(); necks can arise due to the volume of data requested if (child.node-name().equals(nick)) by the clients. Caching data items in memory at { the clients can reduce the volume of data that must String nick = child.string-value(); be obtained from server. Therefore, in our imple- Person_nicks.addElement(nick); mentation we use client data caching technique as } a fundamental technique for improving the perfor- if (child.node-name().equals(name)) mance and scalability of database systems [6]. { There are two basic types of client caching: Sequence attrs = child.attributes(); intra-transaction caching refers to the caching of while(attrs.next()) data within a single transaction; inter-transaction { caching allows clients to keep data cached lo- Node at = ((Item)attrs.getItem()).asNode(); cally even across transaction boundaries. Intra- If(at.node-name().equals(nick)) transaction caching requires only that a client appli- { cation be able to manage its own buffer pool (cache). String nick = at.string-value(); This is because the transaction mechanisms will en- Person_nicks.addElement(nick); sure that any data that has been accessed by a trans- } action (and hence, brought into a clients memory) } is valid. In contrast, inter-transaction data caching } raises the need for a cache consistency protocol to } ensure the application always see a consistent (seri- } alizable) view of the database. This greatly compli- } cates the issue [5]. } In this paper we consider the implementation of while(seq2.next()) intra-transaction caching technique as it is easily im- { plemented that allows us to focus on navigational Atom atom = ((Item)seq2.getItem()).asAtom(); aspects. String pet_nick = atom.value(); if (person_nicks.contain(pet_nick)) 4.3 Representation of Data Items in Client’s System.out.println(pet_nick); Cache } According to the intra-transaction caching technique application obtains data items from the server dur- ing a transaction, stores some of the data items in its 4 Implementation local cache, and when the transaction commits, the In this section we present our proposal for imple- cache flushes. Thus, cache always contains the data mentation of the XML DBMS API described in this that was obtained by the current transaction only. paper. Before going into detail we consider the basic Now we consider how the data items are represented assumptions. in client cache. As it is shown in our example in Sec- tion 3, application uses the executeQuery method to 4.1 Assumptions pass the XQuery query to the server for execution. If the execution succeeds application obtains the Se- According to the common terminology under the quence as a result. When an object of the Sequence term driver we understand the implementation of interface is returned, the portion of the first item (or the whole item if it is smaller than specified portion) OID is used to identify the object uniquely and is shipped into the applications cache. to implement inter-object references. It is indepen- In cache XML data is represented as a set of ob- dent of the state of the object, and it is not changed jects. These objects form trees referring one to an- during the whole life-time of the object. other. The kind of object references we discuss in Basically, there are two kinds of OIDs: physical the next section. Each object represents a node of a and logical OIDs [2, 3]. A physical OID is con- or an atomic value and can be associated with structed in such a way that it contains the perma- the Node or Atom the elements of the Navigational nent address of the object it refers to (i.e., the id of API. the disk, the page number and the slot). An object The atomic value nodes are simple, they contain can directly be loaded from server on the basis of a the value and the type of the value and do not refer physical OID. On the other side, the reorganization to other nodes. and reclustering of the database is difficult because The objects that are nodes have more compli- an object cannot simply be moved to another place if cated structure. Each object that is a node is one of physical OIDs are used. To move an object, a place- the seven node kinds: document, element, attribute, holder must be established; but, these placeholders text, namespace, processing instruction, and com- annihilate the advantage of physical OIDs as often ment. It contains all the information that is needed two page faults are required to read an object on the to implement the accessors-functions that are pro- basis of a physical OID and the placeholder, and the vided by the Node interface of the API: storage utilization is reduced as the placeholders of moved objects fragment the data pages. • Base-uri property; In Sedna XML DBMS logical OIDs are used: ev- ery node of XML data on the server is associated • Kind of a node; with its logical OID. Logical OIDs are more flexi- • The value of a node; ble than physical OIDs, since they do not contain the permanent address of the object they reference. • The type of a node; Objects can, therefore, be moved freely, and thus, the database can well be reorganized if logical OIDs • Reference to a parent node; are used. There are number of techniques to imple- ment logical OIDs [2], in this paper we will not go • Reference to a first child node; into dicussion of how they are implemented in Sedna DBMS. So, in our implementation of the Sedna API • Reference to a next sibling node; we rely on the fact that logical OID is provided for • Reference to a first attribute node; a node by the server. Thus, every object in client applications cache • Reference to a first namespace node. contains its OID. The object reference to another object, that was talk about in section 4.3, is the The values of these fields depend on the node kind OID of the referenced object. and on the node itself. That is, for example, doc- If the object is in cache, application needs to lo- ument nodes has NULL reference to parent node, at- cate it in the cache [9, 3]. The cache object table tribute nodes has NULL reference to a first child node (COT), in which all objects that are in cache are and their reference to a sibling node is a reference to registered, realizes the mapping from OIDs to client the next attribute node. main-memory addresses. Note, every node has reference only to the first child (attribute, namespace). Due to the reference 4.5 Application Iteraction with Cache Ob- to a next child (attribute, namespace) every node of jects a tree is reachable, i.e. these references is enough for exhaustive tree traversal. Such a node struc- In this section we consider what caching means for ture provides an advatages: first, each node is of a application navigating over a big portion of data us- fixed structure; second, each node is of a compact ing API and how it iteracts with cache objects. structure, since it does not contain references to all Application working with API can obtain an ob- children (attributes, namespaces). ject of Node class (see example from Section 3). Ob- By means of the references containg in each node ject of Node class encapsulates an OID of the cor- every node of a tree is reachable directly or indi- responding node (see figure 2). The object of Node rectly via the parent, children, attributes or names- class implements accessors-functions working with paces accessors-functions. cached object through COT. Having OID, it reaches the node from cache through COT and obtaines all 4.4 Unique Object Identifiers the information, contained in cached object, needed to implement accessors-functions. Thus, application While designing this implementation we confronted iteracts with cache object indirectly, through the with such questions as: how to determine what piece COT. of the data from the server is in cache, what is the Such indirect iteraction has an important advan- objects reference to an object that is not in cache? tage. Application can operate with Node objects All these leads to the need to associate with an ob- equally, and its work is independent of the fact if ject its unique object identirier (OID). the object is in cache at the moment or has been Client 5 Related Work

Application . . . From the works related to the issue discussed in the paper, we would like to mention XML:DB API Node node = item.asNode(); [12, 10]. XML:DB Working Group has made an OID 1 . . . effort to develop API for XML DBMS that would become a common standard for XML DBMS like COT Cache JDBC for relational DBMS. A few XML DBMS now OID 1 11 provide their implementation of the XML:DB API, OID 2 5 but in whole XML:DB API has not made a great impression on the XML database developers. In the Sedna XML DBMS we do not use this XML:DB proposal because of the reason that it pro- vides DOM as navigational subinterface. Why DOM does not suit for navigation over XML data we have Server discussed in 2.4.

Figure 2: Application Iteraction with Cache Objects 6 Conclusion flushed. Every time when application operates with In this paper design and implementation of API for its object of the Node class it consults the COT, XML DBMS are provided. The focus was made and, if the COT doesnt contain the OID of the ob- upon the navigation over XML data. We discussed ject, this object is shipped from the server into the the features of the navigation over XML data, com- applications cache. pared them with those for relational data and on To illustrate aforesaid, we return to our example. this basis provided the design of Navigational API Sequence seq1 = as part of the whole API. We also provided our pro- st1.executeQuery posal for implementation the Navigational API for (document(\’person\’)/*/person); poorly resourced clients. This proposal is used in the Sedna XML DBMS. As a result of query execution application obtains the object of Sequence class. That means a portion of first item of the result sequence is shipped into References the applications cache. [1] ”Document Object Model (DOM)”, Item item = seq1.getItem(); World Wide Web Consortium, If (item.isNode()) http://www.w3.org/DOM/. { Node node = item.asNode(); [2] Andre Eickler, Carsten A.Gerlholf, Donald } Kossmann, ”A Performance Evaluation of OID Mapping Techniques”. Proceedings of the 21st Here application is provided with an object node VLDB Conference Zurich, Switzerland, 1995. of the Node class. It encapsultes OID and iteract with cache object through COT. [3] J. Eliot, B.Moss, ”Working with Persistent Ob- jects: To Swizzle or Not To Swizzle”. 4.6 Cache Flush [4] ”Extesible Markup Language (XML) 1.0”, For the sake of completeness we consider cache flush W3C Recomendation. 2nd edition (2000), mechanism in this section. http://www.w3.org/TR/2000/REC-xml- During application navigation over data, the data 20001006 items are shipped from the server into the applica- tions cache. At some moment cache become full and [5] Michael J. Franklin, Michael J. Carey, Miron to put a new piece of data into the cache another Livny, ”Transactional Client-Server Cache Con- piece of data must be flushed from the cache. Such sistency: Alternatives and Performance”. replacement performs according to some replace- ment policy. In our implementation we use com- [6] Michael J. Franklin, Donald Kossmann, ”Cache mon cache replacement policy named LRU (Least Investment Strategies”. Recently Used). According to LRU policy the objects that are [7] ”JDBC 3.0 Specification”, Sun Microsystems, least recently used are flushed from the cache. For Inc. October 2001. this purpose we add a column to our COT. In that column the number of object usage by application is [8] M. Grinev, A. Fomichev, S. Kuznetsov, K. registered. That is, every time the application iter- Antipin, A. Boldakov, D. Lizorkin, L. Novak, acts with the cache object through COT, the index M. Rekouts, P. Pleshachkov, ”Sedna: A Na- of this column increases by one. When the cache is tive XML DBMS”, Submitted to International full, the objects that have minimal indexes of usage Workshop on XQuery Implementation, Experi- in COT are flushed. ence and Perspectives (XIME-P), 2004. [9] Alfons Kemper, Donald Kossmann, ”Adaptable Pointer Swizzling Strategies in Object Bases: Design, Realization, and Quantitative Analy- sis”, VLDB Journal, 4, 519-567 (1995), Malcom Atkinson, Editor. [10] Kimbro Staken, ”An Introduction to the XML:DB API”, http://www.xml.com. [11] Lien Hua Chou, Herry Hamidjaja and Hongyan Yang, ”Caching Techniques in Object Oriented Database”. [12] XML:DB Initiative for XML Databases, ”Application Program- ming Interface for XML Databases”, http://www.xmldb.org/xapi/index.html. [13] ”XMLSchema Part 2”, World Wide Web Con- sortium, 2002. [14] ”XQuery 1.0 and XPath 2.0 Data Model”, W3C Working Draft. 02 May 2003.