Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

The fact that updates are applied only at the end of a script execution has two consequences on programming, one disturbing, one pleasant:

  • The disturbing consequence is that you don't see your updates until the end, therefore you cannot build on your changes to make other changes.

    An example: suppose you have elements named PERSON. Inside a PERSON there can be a list of BID elements (representing bids made by this person), and you want the BID elements to be wrapped in a BIDS element. But initially the PERSON has no BIDS child.

    Initially:

    Code Block
    languagexml
    <PERSON id="p0103">
      <NAME>Jane</NAME>
    </PERSON>

    We want to insert <BID id="b0022">data</BID> to obtain:

    Code Block
    languagexml
    <PERSON id="p0103">
      <NAME>Jane</NAME>
      <BIDS>
         <BID id="b0022">data</BID>
      <BIDS>
    </PERSON>

    Classically, for example using the DOM, we would proceed in two steps:

    1. If there is no BIDS element inside PERSON, then create one

    2. then insert the BID element inside the BIDS element

    In XQuery Update this would (incorrectly) be written like this:

    Code Block
    languagexml
    declare updating function insert-bid($person, $bid)
    {
      if(empty($person/BIDS))
        then insert node <BIDS/> into $person
        else (),
      insert node $bid as last into $person/BIDS
    }


    Note

    Don't try that: it won't work! Why?
    Because the BIDS element will be created only at the very end, therefore the instruction insert ... as last into $person/BIDS will not find any node matching $person/BIDS, hence throw an execution error.

    So what is a correct way of doing ? We need a self-sufficient solution for each of the two cases:

    Code Block
    languagexml
    declare updating function insert-bid($person, $bid)
    {
     if(empty($person/BIDS))
       then insert node <BIDS>{$bids}</BIDS> into $person
       else insert node $bid as last into $person/BIDS
    }


  • The pleasant consequence is that the document(s) on which you are working are stable during execution of your script. You can rest assured that you are not sawing the branch you are sitting on. For example you can quietly write:

    Code Block
    languagexml
    for $x in collection(...)//X
    return delete node $x

    This is perfectly predictable and won't stop prematurely. Or you can replicate an element after itself without risking looping forever:

    Code Block
    languagexml
    for $x in collection(...)//X
    return insert node $x after $x