How to use the "translate" Xpath function on a node-set
Solution 1
I know I can find-replace a single item using this xpath
/xmldoc/items/item[1]/translate(text(),'-','')
Which will return
"abc"
however, how do I do this for the entire set?
This cannot be done with a single XPath 1.0 expression.
Use the following XPath 2.0 expression to produce a sequence of strings, each being the result of the application of the translate()
function on the string value of the corresponding node:
/xmlDoc/items/item/translate(.,'-', '')
Solution 2
The translate
function accepts in input a string and not a node-set. This means that writing something like:
"translate(/xmlDoc/items/item/text(),'-','')"
or
"translate(/xmlDoc/items/item,'-','')"
will result in a function call on the first node only (item[1]
).
In XPath 1.0 I think you have no other chances than doing something ugly like:
"concat(translate(/xmlDoc/items/item,'-',''),
translate(/xmlDoc/items/item[2],'-',''))"
Which is privative for a huge list of items and returns just a string.
In XPath 2.0 this can be solved nicely using for expressions:
"for $item in /xmlDoc/items/item
return replace($item,'-','')"
Which returns a sequence type:
abc cde
PS Do no confuse function calls with location paths. They are different kind of expressions, and in XPath 1.0 can not be mixed.
Comments
-
Eran Medan almost 2 years
I have an XML document that contains items with dashes I'd like to strip
e.g.
<xmlDoc> <items> <item>a-b-c</item> <item>c-d-e</item> <items> </xmlDoc>
I know I can find-replace a single item using this xpath
/xmldoc/items/item[1]/translate(text(),'-','')
Which will return
"abc"
however, how do I do this for the entire set?
This doesn't work
/xmldoc/items/item/translate(text(),'-','')
Nor this
translate(/xmldoc/items/item/text(),'-','')
Is there a way at all to achieve that?
-
Emiliano Poggi about 13 yearsI know that XPath 2.0 path expressions has been improved a lot. But it's new to me to see a function call appended to the path +1. Is this a XPath 2.0 generally applicable function call syntax? It can not be evinced (at first seen) from the specs.
-
Dimitre Novatchev about 13 years@empo: Yes. And yes again, I have raised this issue -- this can oncly be deducted by studying the XPath 2.0 grammar rules. The answer I got was that "A W3C Spec isn't a tutorial or a book". :( Perhaps @Michael Kay can comment on this?
-
Emiliano Poggi about 13 yearsEven from grammar rules this is not easily deducible. I'll read them better. Thanks once more.
-
Arup Rakshit almost 11 yearsIn this expression
/xmlDoc/items/item/translate(.,'-', '')
why don't usetext()
? asking for knowledge gaining purpose for myself.. -
Dimitre Novatchev almost 11 years@Babai, I favor brevity, so I chose the shorter expression.
-
Arup Rakshit almost 11 years@DimitreNovatchev Thanks for confirming.. so when
.
is being used means,it is the context node..right? then on that context nodestring()
function is being applied.. am i correct? -
Dimitre Novatchev almost 11 years@Babai, Yes, because the 1st argument of translate() must be of type xs:string
-
Arup Rakshit almost 11 years@DimitreNovatchev Sir - I wrote this to collect
"//txt()"
the text nodes..,But I want usenormalize-space
,to strip the texts during the selection,how to do that? please help..! -
Dimitre Novatchev almost 11 years@Babai, This cannot be done with a single XPath 1.0 expression. Also, the test is
text()
-- nottxt()
.In XPath 2.0 one can write://text()/normalize-space(.)
-
Arup Rakshit almost 11 yearsI do have this
<div> Hello<br>My name is McOmghall</br> </div>
.. and I want the output asHello My name is McOmghall
.. So I usedstring(//div)
.. But it is not giving that.. can this be done usingxpath1.0
?