Copyright © 2011 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C liability, trademark and document use rules apply.
This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.
This is a Working Group Note as described in the Process Document. It has been developed by the W3C XML Query Working Group, which is part of the XML Activity.
This document incorporates a number of use cases that guided the development of XQuery Update Facility 1.0 during its design and development.
Please report errors in this document using W3C's public Bugzilla system (instructions can be found at http://www.w3.org/XML/2005/04/qt-bugzilla). If access to that system is not feasible, you may send your comments to the W3C XSLT/XPath/XQuery public comments mailing list, public-qt-comments@w3.org. It will be very helpful if you include the string “[UPDUC]” in the subject line of your report, whether made in Bugzilla or in email. Please use multiple Bugzilla entries (or, if necessary, multiple email messages) if you have more than one comment to make. Archives of the comments and responses are available at http://lists.w3.org/Archives/Public/public-qt-comments/.
Publication as a Working Group Note does not imply endorsement by the W3C Membership. At the time of publication, work on this document was considered complete and no further revisions are anticipated. It is a stable document and may be used as reference material or cited from another document. However, this document may be updated, replaced, or made obsolete by other documents at any time.
This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.
1 Use Cases
for XQuery Updates
1.1 Use Case "R" - Updating
Relational Data
1.1.1 Description
1.1.2 Document Type Definition (DTD)
1.1.2.1
Schema for users.xml
1.1.2.2
Schema for items.xml
1.1.2.3
Schema for bids.xml
1.1.3 Input Data
1.1.4 Updates and Results
1.1.4.1
Q1
1.1.4.2
Q2
1.1.4.3
Q3
1.1.4.4
Q4
1.1.4.5
Q5
1.1.4.6
Q6
1.1.4.7
Q7
1.1.4.8
Q8
1.1.4.9
Q9
1.2 Use
Case "Address Book" - synchronizing address book entries
1.2.1 Input Data
1.2.2 Q1
1.3 Use Case
"SOAP" - processing messages
1.3.1 Input Data
1.3.2 Q1
1.4 Use Case
"Namespaces" - moving elements from one namespace to
another
1.4.1 Description
1.4.2 Schema for the grant
application
1.4.3 Input Data
1.4.4 Q1
1.5 Use case
"Parts" - modifying recursive documents
1.5.1 Input data
1.5.2 Q1
1.5.3 Q2
1.5.4 Q3
1.5.5 Q4
1.5.6 Q6
1.6 Use case
"Nil"
1.6.1 XML Schema
1.6.2 Sample input data
("employees.xml")
1.6.3 Q1
A Normative
References
B Revision Log
(Non-Normative)
B.1 Changes in
internal WD
B.2 28 Aug 2007
Publication
The use cases listed below were created by the XML Query Working Group to illustrate important applications for an XML update facility. Each use case is focused on a specific application area, and contains a Document Type Definition (DTD) and example input data. Each use case specifies a set of updates that might be applied to the input data, and the expected resulting value of the modified input for each update. Since the English description of each query is concise, the expected results form an important part of the definition of each update directive. These use cases are inspired by the W3C XQuery Update Facility Requirements document.
These use cases represent a snapshot of an ongoing work. Some important application areas and important operations are not yet adequately covered by a use case. The XML Query Working Group reserves the right to add, delete, or modify individual queries or whole use cases as the work progresses. The presence of a query in this set of use cases does not necessarily indicate that the query will be expressible in the XQuery Update Facility to be created by the XML Query Working Group.
One important use of an XML update language will be to update data stored in relational databases. This use case describes a set of such possible updates.
This use case is based on performing updates on the data used in Use Case "R" from the [XML Query Use Cases]. The sample data from this Use Case is copied below for convenience, and exactly match the data found in the XQuery 1.0 Use Cases. Instead of DTDs, we describe this data with W3C XML Schemas.
The data represents a relational database used by an online auction. The auction maintains a USERS table containing information on registered users, each identified by a unique userid, who can either offer items for sale or bid on items. An ITEMS table lists items currently or recently for sale, with the userid of the user who offered each item. A BIDS table contains all bids on record, keyed by the userid of the bidder and the item number of the item to which the bid applies.
The three tables used by the online auction are below, with their column-names indicated in parentheses.
USERS ( USERID, NAME, RATING ) ITEMS ( ITEMNO, DESCRIPTION, OFFERED_BY, START_DATE, END_DATE, RESERVE_PRICE ) BIDS ( USERID, ITEMNO, BID, BID_DATE )
This use case is based on three separate input documents named users.xml, items.xml, and bids.xml. Each of the documents represents one of the tables in the relational database described above, using the following DTDs:
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"> <xs:element name="users"> <xs:complexType> <xs:sequence> <xs:element minOccurs="0" maxOccurs="unbounded" ref="user_tuple"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="user_tuple"> <xs:complexType> <xs:sequence> <xs:element ref="userid"/> <xs:element ref="name"/> <xs:element minOccurs="0" ref="rating"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="userid" type="xs:string"/> <xs:element name="name" type="xs:string"/> <xs:element name="rating" type="xs:string"/> </xs:schema>
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"> <xs:element name="items"> <xs:complexType> <xs:sequence> <xs:element minOccurs="0" maxOccurs="unbounded" ref="item_tuple"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="item_tuple"> <xs:complexType> <xs:sequence> <xs:element ref="itemno"/> <xs:element ref="description"/> <xs:element ref="offered_by"/> <xs:element minOccurs="0" ref="start_date"/> <xs:element minOccurs="0" ref="end_date"/> <xs:element minOccurs="0" ref="reserve_price"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="itemno" type="xs:string"/> <xs:element name="description" type="xs:string"/> <xs:element name="offered_by" type="xs:string"/> <xs:element name="start_date" type="xs:string"/> <xs:element name="end_date" type="xs:string"/> <xs:element name="reserve_price" type="xs:string"/> </xs:schema>
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"> <xs:element name="bids"> <xs:complexType> <xs:sequence> <xs:element minOccurs="0" maxOccurs="unbounded" ref="bid_tuple"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="bid_tuple"> <xs:complexType> <xs:sequence> <xs:element ref="userid"/> <xs:element ref="itemno"/> <xs:element ref="bid"/> <xs:element ref="bid_date"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="userid" type="xs:string"/> <xs:element name="itemno" type="xs:string"/> <xs:element name="bid" type="xs:string"/> <xs:element name="bid_date" type="xs:string"/> </xs:schema>
The following data is an excerpt of the initial state for Q1. In this particular use case, each update begins with the state resulting from the prior update.
<items> <item_tuple> <itemno>1001</itemno> <description>Red Bicycle</description> <offered_by>U01</offered_by> <start_date>1999-01-05</start_date> <end_date>1999-01-20</end_date> <reserve_price>40</reserve_price> </item_tuple> ... Snip ... </items> <users> <user_tuple> <userid>U01</userid> <name>Tom Jones</name> <rating>B</rating> </user_tuple> ... Snip ... </users> <bids> <bid_tuple> <userid>U02</userid> <itemno>1001</itemno> <bid>35</bid> <bid_date>1999-01-07</bid_date> </bid_tuple> <bid_tuple> ... Snip ... </bids>
The entire data set is represented by the following tables:
USERID | NAME | RATING |
U01 | Tom Jones | B |
U02 | Mary Doe | A |
U03 | Dee Linquent | D |
U04 | Roger Smith | C |
U05 | Jack Sprat | B |
U06 | Rip Van Winkle | B |
ITEMNO | DESCRIPTION | OFFERED_BY | START_DATE | END_DATE | RESERVE_PRICE |
1001 | Red Bicycle | U01 | 1999-01-05 | 1999-01-20 | 40 |
1002 | Motorcycle | U02 | 1999-02-11 | 1999-03-15 | 500 |
1003 | Old Bicycle | U02 | 1999-01-10 | 1999-02-20 | 25 |
1004 | Tricycle | U01 | 1999-02-25 | 1999-03-08 | 15 |
1005 | Tennis Racket | U03 | 1999-03-19 | 1999-04-30 | 20 |
1006 | Helicopter | U03 | 1999-05-05 | 1999-05-25 | 50000 |
1007 | Racing Bicycle | U04 | 1999-01-20 | 1999-02-20 | 200 |
1008 | Broken Bicycle | U01 | 1999-02-05 | 1999-03-06 | 25 |
USERID | ITEMNO | BID | BID_DATE |
U02 | 1001 | 35 | 1999-01-07 |
U04 | 1001 | 40 | 1999-01-08 |
U02 | 1001 | 45 | 1999-01-11 |
U04 | 1001 | 50 | 1999-01-13 |
U02 | 1001 | 55 | 1999-01-15 |
U01 | 1002 | 400 | 1999-02-14 |
U02 | 1002 | 600 | 1999-02-16 |
U03 | 1002 | 800 | 1999-02-17 |
U04 | 1002 | 1000 | 1999-02-25 |
U02 | 1002 | 1200 | 1999-03-02 |
U04 | 1003 | 15 | 1999-01-22 |
U05 | 1003 | 20 | 1999-02-03 |
U01 | 1004 | 40 | 1999-03-05 |
U03 | 1007 | 175 | 1999-01-25 |
U05 | 1007 | 200 | 1999-02-08 |
U04 | 1007 | 225 | 1999-02-12 |
The underlying database system has the following referential integrity constraints:
A foreign key on the BIDS table requires that BIDS.USERID contains a value that is found in USERS.USERID
A foreign key on the BIDS table requires that BIDS.ITEMNO contains a value that is found in ITEMS.ITEMNO
Add a new user (with no rating) to the users.xml view.
Solution in the XQuery Update Facility:
insert nodes <user_tuple> <userid>U07</userid> <name>Annabel Lee</name> </user_tuple> into doc("users.xml")/users
Expected resulting content of users.xml:
<users> <user_tuple> <userid>U01</userid> <name>Tom Jones</name> <rating>B</rating> </user_tuple> <user_tuple> <userid>U02</userid> <name>Mary Doe</name> <rating>A</rating> </user_tuple> ... Snip ... <user_tuple> <userid>U06</userid> <name>Rip Van Winkle</name> <rating>B</rating> </user_tuple> <user_tuple> <userid>U07</userid> <name>Annabel Lee</name> </user_tuple> </users>
Enter a bid for user Annabel Lee on February 1st, 1999 for 60 dollars on item 1001.
Solution in the XQuery Update Facility:
let $uid := doc("users.xml")/users/user_tuple[name="Annabel Lee"]/userid return insert nodes <bid_tuple> <userid>{data($uid)}</userid> <itemno>1001</itemno> <bid>60</bid> <bid_date>1999-02-01</bid_date> </bid_tuple> into doc("bids.xml")/bids
Expected resulting content of bids.xml:
<bids> <bid_tuple> <userid>U02</userid> <itemno>1001</itemno> <bid>35</bid> <bid_date>1999-01-07</bid_date> </bid_tuple> <bid_tuple> <userid>U04</userid> <itemno>1001</itemno> <bid>40</bid> <bid_date>1999-01-08</bid_date> </bid_tuple> ... Snip ... <bid_tuple> <userid>U01</userid> <itemno>1002</itemno> <bid>400</bid> <bid_date>1999-02-14</bid_date> </bid_tuple> ... Snip ... <bid_tuple> <userid>U04</userid> <itemno>1007</itemno> <bid>225</bid> <bid_date>1999-02-12</bid_date> </bid_tuple> <bid_tuple> <userid>U07</userid> <itemno>1001</itemno> <bid>60</bid> <bid_date>1999-02-01</bid_date> </bid_tuple> </bids>
Insert a new bid for Annabel Lee on item 1002, adding 10% to the best bid received so far for this item.
Solution in the XQuery Update Facility:
let $uid := doc("users.xml")/users/user_tuple[name="Annabel Lee"]/userid let $topbid := max(doc("bids.xml")/bids/bid_tuple[itemno=1002]/bid) return insert nodes <bid_tuple> <userid>{data($uid)}</userid> <itemno>1002</itemno> <bid>{$topbid*1.1}</bid> <bid_date>1999-02-01</bid_date> </bid_tuple> into doc("bids.xml")/bids
Expected resulting content of bids.xml:
<bids> <bid_tuple> <userid>U02</userid> <itemno>1001</itemno> <bid>35</bid> <bid_date>1999-01-07</bid_date> </bid_tuple> ... Snip ... <bid_tuple> <userid>U01</userid> <itemno>1002</itemno> <bid>400</bid> <bid_date>1999-02-14</bid_date> </bid_tuple> ... Snip ... <bid_tuple> <userid>U04</userid> <itemno>1007</itemno> <bid>225</bid> <bid_date>1999-02-12</bid_date> </bid_tuple> ... Snip ... <bid_tuple> <userid>U07</userid> <itemno>1002</itemno> <bid>1320</bid> <bid_date>1999-03-05</bid_date> </bid_tuple> </bids>
The best bid for item 1002 had been at 1200, thus Annabel's bid is at 1320.
Set Annabel Lee's rating to B.
Solution in the XQuery Update Facility:
let $user := doc("users.xml")/users/user_tuple[name="Annabel Lee"] return if ($user/rating) then replace value of node $user/rating with "B" else insert node <rating>B</rating> into $user
Expected resulting content of users.xml:
<users> <user_tuple> <userid>U01</userid> <name>Tom Jones</name> <rating>B</rating> </user_tuple> <user_tuple> <userid>U02</userid> <name>Mary Doe</name> <rating>A</rating> </user_tuple> ... Snip ... <user_tuple> <userid>U06</userid> <name>Rip Van Winkle</name> <rating>B</rating> </user_tuple> <user_tuple> <userid>U07</userid> <name>Annabel Lee</name> <rating>B</rating> </user_tuple> </users>
Place a bid for Annabel Lee on item 1007, adding 10% to the best bid received so far on that item, but only if the bid amount does not exceed a given limit. The first query illustrates the desired behavior if the limit is exceeded.
Solution in the XQuery Update Facility:
let $uid := doc("users.xml")/users/user_tuple[name="Annabel Lee"]/userid let $topbid := max(doc("bids.xml")/bids/bid_tuple[itemno=1007]/bid) where $topbid*1.1 <= 200 return insert nodes <bid_tuple> <userid>{data($uid)}</userid> <itemno>1007</itemno> <bid>{$topbid*1.1}</bid> <bid_date>1999-02-01</bid_date> </bid_tuple> into doc("bids.xml")/bids
Expected resulting content of bids.xml:
<bids> <bid_tuple> <userid>U02</userid> <itemno>1001</itemno> <bid>35</bid> <bid_date>1999-01-07</bid_date> </bid_tuple> ... Snip ... <bid_tuple> <userid>U04</userid> <itemno>1007</itemno> <bid>225</bid> <bid_date>1999-02-12</bid_date> </bid_tuple> </bids>
In the above, adding 10% to the best bid on item 1007 would have required a bid of 237, which is more than the allowed limit of 200. Thus, the bids.xml document does not change.
Place a bid for Annabel Lee on item 1007, adding 10% to the best bid received so far on that item, but only if the bid amount does not exceed 500. This illustrates the behavior when the resulting value is within the limit.
Solution in the XQuery Update Facility:
let $uid := doc("users.xml")/users/user_tuple[name="Annabel Lee"]/userid let $topbid := max(doc("bids.xml")/bids/bid_tuple[itemno=1007]/bid) where $topbid*1.1 <= 500 return insert nodes <bid_tuple> <userid>{data($uid)}</userid> <itemno>1007</itemno> <bid>{$topbid*1.1}</bid> <bid_date>1999-02-01</bid_date> </bid_tuple> into doc("bids.xml")/bids
Expected resulting content of bids.xml
<bids> <bid_tuple> <userid>U02</userid> <itemno>1001</itemno> <bid>35</bid> <bid_date>1999-01-07</bid_date> </bid_tuple> ... Snip ... <bid_tuple> <userid>U04</userid> <itemno>1007</itemno> <bid>225</bid> <bid_date>1999-02-12</bid_date> </bid_tuple> <bid_tuple> <userid>U07</userid> <itemno>1007</itemno> <bid>237</bid> <bid_date>1999-04-01</bid_date> </bid_tuple> </bids>
Erase user Dee Linquent and the corresponding associated items and bids.
Solution in the XQuery Update Facility:
let $user := doc("users.xml")/users/user_tuple[name="Dee Linquent"] let $items := doc("items.xml")/items/item_tuple[offered_by=$user/userid] let $bids := doc("bids.xml")/bids/bid_tuple[userid=$user/userid] return ( delete nodes $user, delete nodes $items, delete nodes $bids )
An alternative solution is:
let $user := doc("users.xml")/users/user_tuple[name="Dee Linquent"] let $items := doc("items.xml")/items/item_tuple[offered_by=$user/userid] let $bids := doc("bids.xml")/bids/bid_tuple[userid=$user/userid] return delete nodes $user, $items, $bids
The two solutions above highlight the fact that a list of delete operations is equivalent to deleting the list of nodes obtained by concatenating the operands on which the deletes applied.
Expected resulting content of items.xml:
<items> <item_tuple> <itemno>1001</itemno> <description>Red Bicycle</description> <offered_by>U01</offered_by> <start_date>1999-01-05</start_date> <end_date>1999-01-20</end_date> <reserve_price>40</reserve_price> </item_tuple> ... Snip ... <item_tuple> <itemno>1004</itemno> <description>Tricycle</description> <offered_by>U01</offered_by> <start_date>1999-02-25</start_date> <end_date>1999-03-08</end_date> <reserve_price>15</reserve_price> </item_tuple> <item_tuple> <itemno>1007</itemno> <description>Racing bicycle</description> <offered_by>U04</offered_by> <start_date>1999-01-20</start_date> <end_date>1999-02-20</end_date> <reserve_price>200</reserve_price> </item_tuple> <item_tuple> <itemno>1008</itemno> <description>Broken bicycle</description> <offered_by>U01</offered_by> <start_date>1999-02-05</start_date> <end_date>1999-03-06</end_date> <reserve_price>25</reserve_price> </item_tuple> </items>
In the above, items 1005 and 1006, offered by user Dee Linquent, have been erased; item 1007 now directly follows item 1004. Notice that the whole subtrees rooted at the corresponding <item_tuple> elements have been erased.
Expected resulting content of users.xml:
<users> <user_tuple> <userid>U01</userid> <name>Tom Jones</name> <rating>B</rating> </user_tuple> <user_tuple> <userid>U02</userid> <name>Mary Doe</name> <rating>A</rating> </user_tuple> <user_tuple> <userid>U04</userid> <name>Roger Smith</name> <rating>C</rating> </user_tuple> ... Snip ... <user_tuple> <userid>U06</userid> <name>Rip Van Winkle</name> <rating>B</rating> </user_tuple> </users>
In the above, user Dee Linquent has been erased.
Expected resulting content of bids.xml:
<bids> <bid_tuple> <userid>U02</userid> <itemno>1001</itemno> <bid>35</bid> <bid_date>1999-01-07</bid_date> </bid_tuple> <bid_tuple> <userid>U04</userid> <itemno>1001</itemno> <bid>40</bid> <bid_date>1999-01-08</bid_date> </bid_tuple> ... Snip ... <bid_tuple> <userid>U02</userid> <itemno>1002</itemno> <bid>600</bid> <bid_date>1999-02-16</bid_date> </bid_tuple> <bid_tuple> <userid>U04</userid> <itemno>1002</itemno> <bid>1000</bid> <bid_date>1999-02-25</bid_date> </bid_tuple> ... Snip ... <bid_tuple> <userid>U04</userid> <itemno>1007</itemno> <bid>225</bid> <bid_date>1999-02-12</bid_date> </bid_tuple> </bids>
No bids had been placed on items 1005 and 1006 offered by user Dee Linquent. However, Dee Linquent had placed a bid on item 1002; this bid has been erased.
Add the element <comment>This is a bargain !</comment> as the last child of the <item> element describing item 1002.
Solution in the XQuery Update Facility
declare revalidation strict; insert nodes <comment>This is a bargain !</comment> as last into doc("items.xml")/items/item_tuple[itemno=1002]
Expected resulting content of items.xml: The same as the original contents.
The items.xml document is unchanged and an error is raised. This update can not be applied without rendering the document invalid with respect to its schema.
Place a bid for Annabel Lee on item 1010, which does not exist in "items.xml". In this query, we assume that a referential integrity constraint in the underlying database system requires that no bid can be placed on an item unless it exists in the database.
Solution in XQuery:
let $uid := doc("users.xml")/users/user_tuple[name="Annabel Lee"]/userid return insert nodes <bid_tuple> <userid>{data($uid)}</userid> <itemno>1010</itemno> <bid>60</bid> <bid_date>2006-04-23</bid_date> </bid_tuple> into doc("bids.xml")/bids
Expected resulting content of bids.xml:the same as the original contents.
This update violates the previously-mentioned referential integrity constraint. Therefore, its execution raises a dynamic error (see Kinds of Errors in the XQuery specification).
Add a bid for Annabel Lee on item 1002, at a price 5 dollars below the current highest bid. A trigger in the underlying database ensures that a bid cannot be made at a lower price than the highest bid made so far on that item.
Solution in XQuery:
let $uid := doc("users.xml")/users/user_tuple[name="Annabel Lee"]/userid let $topbid := max(doc("bids.xml")//bid_tuple[itemno=1002]/bid) return insert nodes <bid_tuple> <userid>{data($uid)}</userid> <itemno>1002</itemno> <bid>{$topbid - 5.00}</bid> <bid_date>2006-04-23</bid_date> </bid_tuple> into doc("bids.xml")/bids
Expected resulting content of bids.xml: the same as the original contents.
This update causes the previously mentioned trigger to return an error. Therefore, its execution will raise a dynamic error (see Kinds of Errors in the XQuery specification).
In this scenario, an address book is synchronized among a central archive and two local copies. This scenario is inspired by the Unison file synchronizer. During synchronization, Address book entries with the same name element are considered to be the same entry. The order of entries is irrelevant. For simplicity, we assume that entries may be modified, but not inserted or deleted. When the two copies are synchronized, their state is saved into an archival version. Synchronization is performed as follows:
If an entry in one of the two copies is different from the archived one, but the other copy matches the archive, the modified copy is propagated to the archive and to the other copy.
If both copies differ from the archive, but they do not both modify the same element in the entry, or they modify the same element but the modified elements have the same value, then the changes from each copy are propagated to both the archive and the other copy.
If the copies have each modified the same entry, but modified it in different ways, a problem is reported in the log, and neither the archive nor the copies are changed. (For simplicity, we do not attempt to merge updates.)
The XQuery Update Facility is sufficient for the problem as scoped above. For more complex scenarios, the XQuery Scripting Extensions will simplify programming by allowing variable assignment and the ability to view the results of prior updates within a query.
This section describes the data prior to synchronization.
archive.xml: The central archive, before synchronization.
<archived-agenda> <last-synch-time>2005-10-05T10:00</last-synch-time> <entry> <name>Benjamin</name> <contact>benjamin@inria.fr</contact> </entry> <entry> <name>Dario</name> <contact>dario@uni-pisa.it</contact> </entry> <entry> <name>Anthony</name> <contact>tony@uni-toulon.fr</contact> </entry> </archived-agenda>
log.xml: The central log, before synchronization.
<log> </log>
copy1.xml: The first modified copy of the address book.
In this copy, Benjamin's contact has changed from INRIA to University of Versailles, Dario has moved from University of Pisa to University of Paris Sud, and Anthony has moved from University of Toulon to the ENA.
<agenda-version> <entry> <name>Benjamin</name> <contact>benjamin@uni-versailles.fr</contact> </entry> <entry> <name>Dario</name> <contact>dario@uni-parissud.fr</contact> </entry> <entry> <name>Anthony</name> <contact>tony@ena.fr</contact> </entry> </agenda-version>
copy2.xml: The second modified copy of the address book.
In this copy, Benjamin has also moved to University of Versailles, Dario has not moved, and Anthony has moved to the EHESS instead of the ENA:
<agenda-version> <entry> <name>Benjamin</name> <contact>benjamin@uni-versailles.fr</contact> </entry> <entry> <name>Dario</name> <contact>dario@uni-pisa.it</contact> </entry> <entry> <name>Anthony</name> <contact>tony@ehess.fr</contact> </entry> </agenda-version>
Synchronize the three logs as described in the description of this use case.
Solution in the XQuery Update Facility:
for $a in doc("archive.xml")/archived-agenda/entry, $v1 in doc("copy1.xml")/agenda-version/entry, $v2 in doc("copy2.xml")/agenda-version/entry where $a/name = $v1/name and $v1/name = $v2/name return if ($a/contact = $v1/contact and $v1/contact=$v2/contact) then () else if ($v1/contact = $v2/contact) then replace value of node $a/contact with $v1/contact else if ($a/contact = $v1/contact) then ( replace value of node $a/contact with $v2/contact, replace value of node $v1/contact with $v2/contact ) else if ($a/contact = $v2/contact) then ( replace value of node $a/contact with $v1/contact, replace value of node $v2/contact with $v1/contact ) else ( insert node <fail> <arch>{ $a }</arch> <v1>{ $v1 }</v1> <v2>{ $v2 }</v2> </fail> into doc("log.xml")/log ) , replace value of node doc("archive.xml")/*/last-synch-time with current-dateTime()
Expected Results:
Expected results of the agenda synchronization: A synchronization of the two versions of the agenda made on April 23th, 2006, at noon, should have the following impact on the archive, versions, and log.
Note:
In the following XML results, the comments (shown in italic font) were not created by the update directives, and are not part of the result documents. They have been added to explain where each part of a result document comes from.
archive.xml
<archived-agenda> <last-synch-time>2006-04-23T12:00</last-synch-time> <entry> <name>Benjamin</name> copied from the modified entries <contact>benjamin@uni-versailles.fr</contact> </entry> <entry> <name>Dario</name> copied from first modified version <contact>dario@uni-parissud.fr</contact> </entry> <entry> <name>Anthony</name> unchanged due to conflict <contact>tony@uni-toulon.fr</contact> </entry> </archived-agenda>
log.xml
<log> update failure details <fail> <arch> archived agenda version <entry> <name>Anthony</name> <contact>tony@uni-toulon.fr</contact> </entry> </arch> <v1> first modified version <entry> <name>Anthony</name> <contact>tony@ena.fr</contact> </entry> </v1> <v2> second modified version <entry> <name>Anthony</name> <contact>tony@ehess.fr</contact> </entry> </v2> </fail> </log>
copy1.xml
<agenda-version> <entry> <name>Benjamin</name> kept after synchronization <contact>benjamin@uni-versailles.fr</contact> </entry> <entry> kept after synchronization <name>Dario</name> <contact>dario@uni-parissud.fr</contact> </entry> <entry> kept after synchronization failure <name>Anthony</name> <contact>tony@ena.fr</contact> </entry> </agenda-version>
copy2.xml
<agenda-version> <entry> kept after synchronization <name>Benjamin</name> <contact>benjamin@uni-versailles.fr</contact> </entry> <entry> value taken from the other modified version <name>Dario</name> <contact>dario@uni-parissud.fr</contact> </entry> <entry> kept after synchronization failure <name>Anthony</name> <contact>tony@ehess.fr</contact> </entry> </agenda-version>
This use case processes the message found in Example 1 of the [SOAP Version 1.2 Part 0:Primer] to produce the message found in Example 2. The original message is not modified, but the new message is a modified copy of the original.
The input data is taken directly from Example 1 of the [SOAP Version 1.2 Part 0:Primer].
<?xml version='1.0' ?> <env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope"> <env:Header> <m:reservation xmlns:m="http://travelcompany.example.org/reservation" env:role="http://www.w3.org/2003/05/soap-envelope/role/next" env:mustUnderstand="true"> <m:reference>uuid:093a2da1-q345-739r-ba5d-pqff98fe8j7d </m:reference> <m:dateAndTime>2001-11-29T13:20:00.000-05:00 </m:dateAndTime> </m:reservation> <n:passenger xmlns:n="http://mycompany.example.com/employees" env:role="http://www.w3.org/2003/05/soap-envelope/role/next" env:mustUnderstand="true"> <n:name>Åke Jógvan Øyvind</n:name> </n:passenger> </env:Header> <env:Body> <p:itinerary xmlns:p="http://travelcompany.example.org/reservation/travel"> <p:departure> <p:departing>New York</p:departing> <p:arriving>Los Angeles</p:arriving> <p:departureDate>2001-12-14</p:departureDate> <p:departureTime>late afternoon</p:departureTime> <p:seatPreference>aisle</p:seatPreference> </p:departure> &l