Absolute Path of an Element found with XQuery

Given a deep XML tree e.g:














I use an XQuery like
for $a in input()/level1[@myid=‘123’]//@attrib where $a = ‘bb’ return $a/… to look for all the elements with attrib=‘bb’.

I now need the absolute path of this entry e.g.:
level1[myid=‘123’]/level2[id=‘4’]/level3[id=‘5’]/level4/level5[id=‘6’]

Since the levels are not always the same, I can’t keep adding /… to get the root since some levels are less deep.
If I could find a way to iterate backwards (since I know that the ids are called ‘id’) I could build it myself.

Anybody can help me with this?

I need to make some corrections here.
What I need is to get the absolute XPath of an Element found with an XQuery.

Given a deep XML tree e.g:
























I use an XQuery like:

for $a in input()/level1[@myid=‘123’]//@attrib where $a = ‘bb’ return $a/…

to look for all the elements with attrib=‘bb’.

I now need the absolute path of this element e.g.:
level1[myid=‘123’]/level2[id=‘4’]/level3[id=‘5’]/level4/level5[id=‘6’]

Since the attribute attrib can be on any level, I can’t keep adding /… in one query to get the root since some levels are less deep.
If I could find a way to iterate backwards (since I know that the ids are called ‘id’) I could build it myself.

Anybody can help me with this?

In the absence of the ancestor axis and of user-defined functions, I can’t see an obvious solution to this requirement.

This suggests taking a step back - this design isn’t going to work, but perhaps some other design will meet the requirements in a different way? What are you really trying to do?

Michael Kay

Thank you very much for the response.

I have an XML whose elements can be changed, deleted and added. This elements can be at different levels within the XML tree hierarchy. I’m using Tamino 4.1.1.1 with the Tamino API for Java and the dom4j data model.

When an element is changed, an attribute is added to it denoting the source of the change. Similarly flags are added on a delete or add. The changing instance provides me with an XPath expression giving me the absolute position of the element to flag.
I use update and insert XQuerys like

update for $a in input()/level1[@myid=‘123’]/level2[@id=‘1’]/elemX do ( replace $a with new value )

update for $a in input()/level1[@myid=‘123’]/level2[@id=‘1’] do ( insert new element into $a)

Later I need to remove this flags. I use the query in my previous posting to find all the elements which have this flags. I need however also to give another instance, the absolute XPath of the elements, which had this flags. The above query however gives me only a partial tree. I need a single query to do this.

I would very much appreciate if you could also give me a tip on an alternative way to do this.

Can’t you just do this?

update for $a in input()//@attrib do delete $a

That will remove all the “attrib” attributes.

Bill

Yes I do my deletes like that.

However as I stated in my previous entry, I also need to give another instance, the absolute XPath of the elements, which had this flags.
Currently that is the difficult part, to somehow navigate backwards up the XML tree up to the root and get an expression like
/level1[@myid=‘123’/level2[@id=‘1’]/elemY
to signal an element which had a change (above a replace).
The changes into the XML and the later forwarding of the information to another instance does not happen simultaneuosly.

I’m not sure I follow. In your original post you wrote:



If you just want to get the root node you can do either:

for $i in input()/level1
where $i//@attrib=‘bb’
return $i

OR

for $i in input()/level1//@attrib
return root($i)

(The queries are a little different in that the second one will return the same document multiple times, if that document has multiple @attrib attributes)

In theory you could modify the second query to return both the root element and the modified element, but when I do that I get a runtime exception for some reason.

for $i in input()/level1//@attrib
return

{root($i)}
{$i/…}


However, both these queries return an XML tree, not an X-Path expression. If you really want an X-path expression I’m not sure how to get that.

Bill

Thanks Bill.

I have realised that what I wanted would not be possible. Actually I wanted a query which would ofcourse give back an XML tree, but I expected only the branches with my search criterium, so that I could navigate from the leaf upto the root and build the XPath myself.

After using your example queries, I did get the XML tree, but essentially containing everything in the document. To find my relevant leafs again would involve too much work.

I have however found another solution independent of XQuery.