17

I need to remove the following characters from a string value using xsl 1.0

*, /, \, #, %, !, @, $, (, ), &

I have come up with the following:

translate(translate(translate(string(//xpath/@value),'.',''),'/',''),',','')

In the above approach, I would have to duplicate the same code many times (one time per character).

How can I achieve the same goal without duplicating the code?

Thanks :-)

Ryan Gates
  • 4,501
  • 6
  • 50
  • 90
dinesh028
  • 2,137
  • 5
  • 30
  • 47

2 Answers2

24

The translate() function accepts as its second and third argument two strings -- not just two characters.

translate(., $string1, '')

produces a string which is the string value of the context (current) node in which any occurence of a character that is in $string1 is deleted.

Therefore you can use:

translate(expressionSelectingNode, "/\#%!@$()&", "")

to delete any of the characters contained in the second argument.

Of course, if the translate() function is used within an XSLT stylesheet (or, generally within an XML document), some special characters, such as < and & must be escaped respectively as &lt; and &amp;.

Using this is so powerful, that one can remove a set of unknown characters:

Imagine that you want to remove from any string all characters that are not numeric. We don't know in advance what characters would be present in the string, therefore we cannot just enumerate them in the second argument of translate(). However we can still delete all these unknown charcters like that:

translate(., translate(., '0123456789', ''), '')

The inner translate() produces the string sans any digits.

The outer translate() deletes all this non-digit characters (found by the inner translate()) from the original string -- therefore what remains are only the digit characters.

Dimitre Novatchev
  • 240,661
  • 26
  • 293
  • 431
  • This was quite helpful to me, but in the `translate(translate(., '0123456789', ''), '')` line, I think the outer translate is missing its first parameter, no? – Beska Dec 26 '17 at 16:49
  • @Beska, No, the outer `translate()` has as its 1st argument the result of the inner `translate()`, and as 2nd argument the empty string. So, the arguments are: 1. `translate(., '0123456789', '')` and 2. `''` – Dimitre Novatchev Dec 26 '17 at 17:54
  • But doesn't translate require three params? (When I tried this code out as-is, it complained about that for me. I had to add the path as a first param.) – Beska Dec 26 '17 at 19:32
  • @Beska You are right -- what is missing here is the 1st argument, which is the context node `.` -- so this must be: `translate(.,translate(., '0123456789', ''), '')` I already edited the answer. Thank you for noticing this! – Dimitre Novatchev Dec 26 '17 at 20:11
17

You simply need translate(//foo/@value, '*\%!@$&', '') in pure XPath respectively inside of an XML document like an XSLT stylesheet you need to escape the ampersand <xsl:value-of select="translate(//foo/@value, '*\%!@$&amp;', '')"/>.

Martin Honnen
  • 160,499
  • 6
  • 90
  • 110