This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 3578 - [UPDUseCases] Issues with May 8th Usecase Draft
Summary: [UPDUseCases] Issues with May 8th Usecase Draft
Status: CLOSED FIXED
Alias: None
Product: XPath / XQuery / XSLT
Classification: Unclassified
Component: Update Facility 1.0 Use Cases (show other bugs)
Version: Working drafts
Hardware: PC Linux
: P2 normal
Target Milestone: ---
Assignee: Jonathan Robie
QA Contact: Mailing list for public feedback on specs from XSL and XML Query WGs
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-08-03 03:20 UTC by Jerome Simeon
Modified: 2011-01-08 00:31 UTC (History)
1 user (show)

See Also:


Attachments
Fixed SOAP query. (3.55 KB, text/x-c++src)
2007-08-17 17:32 UTC, Jonathan Robie
Details

Description Jerome Simeon 2006-08-03 03:20:30 UTC
Use Case "R"
============

Q4: Tries to set Annabel Lee's rating to "B". But Annabel Lee was 
inserted (Q1) without any rating, so "replace value of" would
have an empty target.

Use Case "Parts"
================

The intro talks about a "partlist.xml", but the queries access
a "part-list.xml"

Q3: Neither solution 1, nor solution 3 lead to the expected result.
Solution 1 doesn't delete piston, window and lock.
The recursive function is solution 2 is also incorrect, as it
deletes in "part-tree.xml" at the first call and in "part-list.xml"
at subsequent calls.

Q4: The note says that "as last into" should be used if position is
important, but the expected result shows that the "radio" element
is inserted as the first child of "car", not as the last one.

Use Case "SOAP"
===============

A few typos:
* count($returnDepartingAirports)>1
(the one is missing)
* has a call to currentdateTime() instead of current-dateTime() 
* should use string() instead of string-value()
* call to local:airports($in) fails because $in is undefined;
  local:airports($out//env:Body) should be used

Use Case "Address Book"
=======================

- Typo: a comma is missing after 
"do replace value of $v2/contact with $v1/contact"

I believe the current version of the address book use case raises a 
replace-replace
conflict. The reason is that there is a loop within which we do the same 
replace:

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
...
            do replace value of 
               doc("archive.xml")/*/last-synch-time
            with current-dateTime()

here doc("archive.xml")/*/last-synch-time

keeps pointing to the same node and therefore there will be multiple 
replaces
over the same node in the pending update list, which raises a conflict 
when applying
them.

- Jerome
Comment 1 Jonathan Robie 2007-08-17 17:18:47 UTC
This seems to solve the address book use case - it sure would be easier with the scripting extensions.

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()
Comment 2 Jonathan Robie 2007-08-17 17:31:05 UTC
I believe this fixes the errors in Use Case "SOAP":

<pre>
declare namespace    env="http://www.w3.org/2003/05/soap-envelope"; declare namespace    m="http://travelcompany.example.org/reservation"; declare namespace    n="http://mycompany.example.com/employees"; declare namespace    p="http://travelcompany.example.org/reservation/travel";  (:  A clarification is needed only if there are no  :  airports or more than one for a given city. If  :  there is precisely one, there is no need to  :  ask for information on that city.  :)  declare function local:airportChoices($city as xs:string) {   let $airports := collection("airports")[CITY = $city]   return     if (count($airports) = 0)     then         <error> No airports found for {$city}!</error>     else if (count($airports) > 1)      then         <airportChoices>         {            for $c in $airports/CODE           return (string( $c ), " ")         }        </airportChoices>     else () };  (:  Make sure that each airport is unambiguous. If there is  :  more than one airport for a city, ask for clarification.  :  :  The primer only shows the error condition, so it is not  :  clear what to do if there are no errors. Here, we simply  :  return the airports in the itinerary.  :)  declare function local:airports($in as element(env:Envelope)) {     let $departureDeparting :=        $in//p:departure/p:departing     let $departureDepartingAirports :=        collection("airports")[CITY = $departureDeparting]     let $departureArriving :=        $in//p:departure/p:arriving     let $departureArrivingAirports :=        collection("airports")[CITY = $departureArriving]     let $returnDeparting :=        $in//p:return/p:departing     let $returnDepartingAirports :=        collection("airports")[CITY = $returnDeparting]     let $returnArriving :=        $in//p:return/p:arriving     let $returnArrivingAirports :=        collection("airports")[CITY = $returnArriving]     return        if ( count($departureDepartingAirports)=0 or              count($departureDepartingAirports)>1 or              count($departureArrivingAirports)=0 or              count($departureArrivingAirports)>1 or              count($returnDepartingAirports)=0 or              count($returnDepartingAirports)>1 or              count($returnArrivingAirports)=0 or              count($returnArrivingAirports)>1 )          then           <p:itineraryClarification>             <p:departure>               <p:departing>                 { local:airportChoices($departureDeparting) }               </p:departing>               <p:arriving>                 { local:airportChoices($departureArriving) }               </p:arriving>              </p:departure>             <p:return>               <p:departing>                 { local:airportChoices($returnDeparting) }               </p:departing>               <p:arriving>                 { local:airportChoices($returnArriving) }               </p:arriving>             </p:return>           </p:itineraryClarification>          else            <p:itinerary>             <p:departure>               <p:departing>{$departureDeparting}</p:departing>               <p:arriving>{$departureArriving}</p:arriving>             </p:departure>             <p:return>               <p:departing>{$returnDeparting}</p:departing>               <p:arriving>{$returnArriving}</p:arriving>             </p:return>           </p:itinerary> };  declare variable $msg external;  copy $out := $msg/env:Envelope modify (   replace value of node $out//m:dateAndTime 
     with fn:current-dateTime(),   replace node $out//env:Body    with <env:Body>         { local:airports($out//env:Body) }        </env:Body> ) return $out
</pre>
Comment 3 Jonathan Robie 2007-08-17 17:32:48 UTC
Created attachment 483 [details]
Fixed SOAP query.

I think this fixes the SOAP bug.
Comment 4 Jonathan Robie 2007-08-17 18:48:17 UTC
I think this fixes the Use Case "R" Q4:


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
Comment 5 Jonathan Robie 2007-08-17 19:52:50 UTC
[quote]Q4: The note says that "as last into" should be used if position is
important, but the expected result shows that the "radio" element
is inserted as the first child of "car", not as the last one.[/quote]

But that's the point. I show a query that doesn't specify position, and it winds up first, which might be unexpected. In subsequent text, I then say that you can put it in a particular position, e.g. by specifying "as last".

I don't think this is a bug.
Comment 6 Jonathan Robie 2007-08-17 20:24:11 UTC
[quote]Q3: Neither solution 1, nor solution 3 lead to the expected result.
Solution 1 doesn't delete piston, window and lock.
The recursive function is solution 2 is also incorrect, as it
deletes in "part-tree.xml" at the first call and in "part-list.xml"
at subsequent calls.[/quote]

I believe this is correct for solution 1:


for $pt in doc("part-tree.xml")//part[@name="car"]//part,
     $pl in doc("part-list.xml")//part
where $pt/@partid eq $pl/@partid
return 
   delete nodes $pl

I believe this is correct for solution 2:

declare updating function 
             local:delete-subtree($p as element(part))
  {
      for $child in doc("part-list.xml")//part
      where $p/@partid eq $child/@partof
      return (
        delete nodes $child,
        local:delete-subtree($child)
      )
  };

for $p in doc("part-list.xml")//part[@name="car"]
return 
  local:delete-subtree($p)
Comment 7 Liam R E Quin 2007-08-17 20:28:14 UTC
Closed on behalf of Jonathan; please reopen if it is not satisfactory.
Comment 8 Jerome Simeon 2007-08-17 20:47:19 UTC
Seems to work. Although the use of the 'current-dateTime' function will make
it hard to use it as a test case...
Thanks!
- Jerome

(In reply to comment #1)
> This seems to solve the address book use case - it sure would be easier with
> the scripting extensions.
> 
> 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()
> 

Comment 9 Jerome Simeon 2007-08-17 20:58:51 UTC
Works. Thanks!
- Jerome

(In reply to comment #4)
> I think this fixes the Use Case "R" Q4:
> 
> 
> 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
> 

Comment 10 Jerome Simeon 2007-08-17 21:02:43 UTC
Yes, I agree it's not really a bug. I just think the text can easily been read as saying: "it's appearing last but that's not enforced by the semantics", which I think is what the comment was about.
- Jerome

(In reply to comment #5)
> [quote]Q4: The note says that "as last into" should be used if position is
> important, but the expected result shows that the "radio" element
> is inserted as the first child of "car", not as the last one.[/quote]
> 
> But that's the point. I show a query that doesn't specify position, and it
> winds up first, which might be unexpected. In subsequent text, I then say that
> you can put it in a particular position, e.g. by specifying "as last".
> 
> I don't think this is a bug.
> 

Comment 11 Jerome Simeon 2007-08-17 21:27:37 UTC
Thanks. I think there is still a problem. The local function is defined as taking
elements of type env:Envelop as input, but it's passed an env:Body.

You may want to remove '//env:Body' in the function call.

- Jerome

(In reply to comment #2)
> I believe this fixes the errors in Use Case "SOAP":
> 
> <pre>
> declare namespace    env="http://www.w3.org/2003/05/soap-envelope"; declare
> namespace    m="http://travelcompany.example.org/reservation"; declare
> namespace    n="http://mycompany.example.com/employees"; declare namespace   
> p="http://travelcompany.example.org/reservation/travel";  (:  A clarification
> is needed only if there are no  :  airports or more than one for a given city.
> If  :  there is precisely one, there is no need to  :  ask for information on
> that city.  :)  declare function local:airportChoices($city as xs:string) {  
> let $airports := collection("airports")[CITY = $city]   return     if
> (count($airports) = 0)     then         <error> No airports found for
> {$city}!</error>     else if (count($airports) > 1)      then        
> <airportChoices>         {            for $c in $airports/CODE           return
> (string( $c ), " ")         }        </airportChoices>     else () };  (:  Make
> sure that each airport is unambiguous. If there is  :  more than one airport
> for a city, ask for clarification.  :  :  The primer only shows the error
> condition, so it is not  :  clear what to do if there are no errors. Here, we
> simply  :  return the airports in the itinerary.  :)  declare function
> local:airports($in as element(env:Envelope)) {     let $departureDeparting :=  
>      $in//p:departure/p:departing     let $departureDepartingAirports :=       
> collection("airports")[CITY = $departureDeparting]     let $departureArriving
> :=        $in//p:departure/p:arriving     let $departureArrivingAirports :=    
>    collection("airports")[CITY = $departureArriving]     let $returnDeparting
> :=        $in//p:return/p:departing     let $returnDepartingAirports :=       
> collection("airports")[CITY = $returnDeparting]     let $returnArriving :=     
>   $in//p:return/p:arriving     let $returnArrivingAirports :=       
> collection("airports")[CITY = $returnArriving]     return        if (
> count($departureDepartingAirports)=0 or             
> count($departureDepartingAirports)>1 or             
> count($departureArrivingAirports)=0 or             
> count($departureArrivingAirports)>1 or             
> count($returnDepartingAirports)=0 or             
> count($returnDepartingAirports)>1 or             
> count($returnArrivingAirports)=0 or             
> count($returnArrivingAirports)>1 )          then          
> <p:itineraryClarification>             <p:departure>              
> <p:departing>                 { local:airportChoices($departureDeparting) }    
>           </p:departing>               <p:arriving>                 {
> local:airportChoices($departureArriving) }               </p:arriving>         
>     </p:departure>             <p:return>               <p:departing>          
>       { local:airportChoices($returnDeparting) }               </p:departing>  
>             <p:arriving>                 {
> local:airportChoices($returnArriving) }               </p:arriving>            
> </p:return>           </p:itineraryClarification>          else           
> <p:itinerary>             <p:departure>              
> <p:departing>{$departureDeparting}</p:departing>              
> <p:arriving>{$departureArriving}</p:arriving>             </p:departure>       
>      <p:return>               <p:departing>{$returnDeparting}</p:departing>    
>           <p:arriving>{$returnArriving}</p:arriving>             </p:return>   
>        </p:itinerary> };  declare variable $msg external;  copy $out :=
> $msg/env:Envelope modify (   replace value of node $out//m:dateAndTime 
>      with fn:current-dateTime(),   replace node $out//env:Body    with
> <env:Body>         { local:airports($out//env:Body) }        </env:Body> )
> return $out
> </pre>
> 

Comment 12 Jonathan Robie 2007-08-17 21:35:27 UTC
(In reply to comment #11)
> Thanks. I think there is still a problem. The local function is defined as
> taking
> elements of type env:Envelop as input, but it's passed an env:Body.
> 
> You may want to remove '//env:Body' in the function call.

Ooops - you're right - fixing that now. Thanks!

Jonathan
Comment 13 Jerome Simeon 2007-08-17 23:08:03 UTC
Works! Thanks,
- Jerome

(In reply to comment #6)
> [quote]Q3: Neither solution 1, nor solution 3 lead to the expected result.
> Solution 1 doesn't delete piston, window and lock.
> The recursive function is solution 2 is also incorrect, as it
> deletes in "part-tree.xml" at the first call and in "part-list.xml"
> at subsequent calls.[/quote]
> 
> I believe this is correct for solution 1:
> 
> 
> for $pt in doc("part-tree.xml")//part[@name="car"]//part,
>      $pl in doc("part-list.xml")//part
> where $pt/@partid eq $pl/@partid
> return 
>    delete nodes $pl
> 
> I believe this is correct for solution 2:
> 
> declare updating function 
>              local:delete-subtree($p as element(part))
>   {
>       for $child in doc("part-list.xml")//part
>       where $p/@partid eq $child/@partof
>       return (
>         delete nodes $child,
>         local:delete-subtree($child)
>       )
>   };
> 
> for $p in doc("part-list.xml")//part[@name="car"]
> return 
>   local:delete-subtree($p)
>