How to choose replace or insert function for attribute

I want to update an attribute value into an instance but I don’t know if the attribute is already present or not. replace does not work if the attribute is not already present in the instance and insert does not work if it is. What is the best way to do this in XQuery?

I’m using Tamino 4.4.1

What I’ve tried so far:

I tried using if/then/else to first determine if the attribute is present but I couldn’t get the if/then/else syntax to work. Is this supported yet?

I tried using a squence of expressions in a do clause but I could not get that to work either as follows:

update for $settings in input()//Settings
let $config := root($settings)/Config
where $settings/@UserId=‘admiNIstrator’ and
$config/@System=‘gerry_staging’
do (delete $settings/@MainWindowGeometry
insert attribute MainWindowGeometry {“2x1+1+1”} into $settings)

My current solution is to send two separate queries to Tamino, first delete the attribute then insert it. Is there a more efficient way to do this in a single query?

Thanks in advance,
Allen

Hi Allen,

no I can’t see anything better than what you already achieved.
But what from the query point-of-view looks like two update operations, in fact only results in a single update operation on the database, since the update effects within a query are first accumulated and then simultaneously applied to the stored data.

Regards,
Juliane.

if/then else is supported and working, but…
you cannot use it inside uodate, unfortunately.
So you have to resort to an alternative form of conditions, as given in this code:


update for $settings in input()//Settings
let $config := root($settings)/Config
where $settings/@UserId='admiNIstrator' and
$config/@System='gerry_staging' do ( 
let $exists := ($settings/@MainWindowGeometry) 
where $exists
do replace $settings/@MainWindowGeometry with attribute MainWindowGeometry {"2x1+1+1"} 
let $exists := ($settings/@MainWindowGeometry)
where not ($exists) 
do insert attribute MainWindowGeometry {"2x1+1+1"} into $settings) 

Regards

Harald

or, if you prefer a more compact notation, try:


update for $settings in input()//Settings
let $config := root($settings)/Config
where $settings/@UserId='admiNIstrator' and
          $config/@System='gerry_staging' 
do ( 
let $exists := ($settings/@MainWindowGeometry) 
do(
      replace $settings/@MainWindowGeometry[$exists] 
                  with attribute MainWindowGeometry {"4x1+1+1"} 
      insert attribute MainWindowGeometry {"3x1+1+1"} 
                  into $settings[not($exists)]) )

Thanks Dr. Schoening. I see in your suggested code that you have a sequence of expressions within a do clause. As I stated in my initial post, I could not get that to work. Here is the the code I tried. From my testing, it appears that only the second expression (the insert) gets executed. Can you shed any light on why this might be?

update for $settings in input()//Settings
let $config := root($settings)/Config
where $settings/@UserId=‘admiNIstrator’ and
$config/@System=‘gerry_staging’
do (
delete $settings/@MainWindowGeometry
insert attribute MainWindowGeometry {“2x1+1+1”} into $settings
)

Allen

Hi Allen,

of course I tested teh code before I posted it, so my sequence does work. And I can explain why yours does not:
The model for executing an inert is the following:
on the original document, apply ALL updates in a sequence. Each update has to be valid by itself, without considering the other updates in a sequence. If more than one update operation applies to the same node in a document, he update is rejected (update conflict).
So looking at your statement, the delete is fine, but the insert generates an invalid document because it is assessed without looking at the other update statements, and hence there is already an attribute of the same name. Hope this explanation helps

Regards

Harald

Harald,

Thanks for the clear explanation. I never would have guessed that to be the problem. I would think this information will prove useful to others in the forum.

Allen