Add attribute to existing element in existing document

Hi all.

I am modifying an existing cSO implementation. As part of that modification, I need to add an attribute to an element of a document that already exists in my Tamino database. I’ll need to determine if the element has been placed previously and if so, update the value. I’m not having much luck.

My methodology is to create a Tamino connection in cSO, run the update query and disconnect but it is not working. The original version of the code does not have logic to test if the element exists, but fails with what appears to be a pretty basic error that I have not been able to figure out. The simple code and error message are below. I borrowed the code from another section of the existing sequences and switched the property names and attribute reference. 1 difference in the 2 scenarios is that although both hit the same Tamino document, the original is updating an attribute that already exists.

Does anybody have a suggestion how to revise the code so it works from the cSO Tamino call rather than using an API call?

$OrderNumber and $tripNumber are cSO properties.

update for $a in input()/Order  where $a/@orderNumber="{"$OrderNumber"}" do replace $a/@tripNumber with attribute tripNumber  {{"{"$tripNumber"}"}' 

xbd.error.text = Exception: “javax.xml.transform.TransformerException: A node test that matches either NCName:* or QName was expected.” in sequence “http://localhost:8080/mimsDevelopmentGateway/RequestTripOrders-seq.xml” at line 145.

I guess the problem is in the syntax and the clash of special characters both of XQuery and of cSO.

I would first try with a constant query, without variables, to ensure it works; e.g.:

update for $a in input()/Order  where $a/@orderNumber="AKnownOrderNumber" do replace $a/@tripNumber with attribute tripNumber {{ "ATripNumber" }}

Or maybe this simpler one would also work:

update for $a in input()/Order  where $a/@orderNumber="AKnownOrderNumber" do replace value of node $a/@tripNumber with "ATripNumber"

Once your query is working, I would try to add variables to it, step by step. Maybe the following would correspond to the two above ones:

update for $a in input()/Order  where $a/@orderNumber="{'$OrderNumber'}" do replace $a/@tripNumber with attribute tripNumber {{ "{'$tripNumber'}" }}
update for $a in input()/Order  where $a/@orderNumber="{'$OrderNumber'}" do replace value of node $a/@tripNumber with "{'$tripNumber'}"

Hope this helps

Javier,

Thanks for the post. Unfortunately I tried both of the first 2 versions in your post, with hard-coded values, and got the same error. My theory is that is because the attribute does not exist in the original document, and you can’t update something that doesn’t exist. But that is just a theory and I’m the one who can’t get the code to run, although it looks rather like a parse-time error.

AND the Tamino XQuery tool gives the following using your first examlpe with hard-coded values. Apparently it is not a good avenue for building code to be used in cSO. So where do you develop XQuery code to use in cSO?

Syntax Error at line 2, column 87: of node $a/@tripNumber with “3256” found NCName when expecting any of: “with”, “or”, “and”, “div”, “mod”, “*”, “to”, “intersect”, “union”, “except”, “/”, “//”, “=”, “is”, “!=”, “<=”, “<<”, “>=”, “>>”, “eq”, “ne”, “gt”, “ge”, “lt”, “le”, "< ", “>”, “-”, “+”, “=>”, “|”, “(”, “[”, “treat as”, “sort”, “stable sort”

The first query above, which I understand comes from a running part of your application, works fine to update an existing attribute. If you are getting a syntax error with the XQuery tool, then you must be entering a different query. I just successfully tested the following similar one using Tamino Interactive Interface on a Tamino 4.4.1 server:

update for $a in input()/Empresa
where $a/@NIF="666"
do replace $a/@NIF with attribute NIF { "777" }

If instead of this what you want to do is to add an attribute to a document that does not have it yet, then the above query should run without error, although it won’t do anything. To add a new attribute you should use a query like this one instead:

update for $a in input()/Empresa
where $a/Nombredeempresa="POPO" and not($a/@NIF)
do 
insert attribute NIF {"zz"} into $a

If you don’t check whether the attribute exist and it is already there, the query will fail. Maybe you can do both things in a single query, but I can’t find how (deleting it first and then adding in the same query doesn’t seem to work). Instead, you may always launch the two queries in sequence.

At any rate, first you should forget about cSO and obtain a valid X-Query that does what you want, using Tamino tools. After that, you may deal with cSO escaping issues.

Once you have the right query, you can escape it into cSO properties. For the examples above, this should do, although I didn’t test:

update for $a in input()/Empresa
where $a/Nombredeempresa="POPO" and not($a/@NIF)
do 
insert attribute NIF {{"zz"}} into $a

Once this works, you may start adding variables, which should yield something like:

update for $a in input()/Empresa
where $a/Nombredeempresa="{'$mycSOQueryVariable'}" and not($a/@NIF)
do 
insert attribute NIF {{"{'$mycSOUpdateVariable'}"}} into $a

Hope this helps