Split node value with XPath

14,700

Solution 1

If you have an xpath-2.0 capable API, you can solve this in two ways:

replace technique

Try using:

fn:replace(string,pattern,replace)

e.g.

fn:replace(//path/text(),".*/","")

tokenize technique

You may get some mileage from tokenize:

fn:tokenize(string,pattern)

e.g. (thanks to Martin)

tokenize(/root/path, '\\')[last()]

w3schools xml processing "xsl functions" documentation

Solution 2

While I would use:

tokenize(/*/*, '\\')[last()]

there are also numerous other ways to obtain the desired string:

  codepoints-to-string
    (reverse
      (string-to-codepoints
         (substring-before
            (codepoints-to-string
                 (reverse
                    (string-to-codepoints(/*/*)
                  )
              ),
              '\'
            )
          )
       )
     )

Or:

  substring(/*/*,
            index-of(string-to-codepoints(/*/*),
            string-to-codepoints('\')
            )
            [last()]
          + 1
           )
Share:
14,700
Rise_against
Author by

Rise_against

Updated on July 20, 2022

Comments

  • Rise_against
    Rise_against almost 2 years

    Is there some kind of split() function in XPath? Say I have this XML:

    <root>
       <path>C:\folder\filename</path>
    </root>
    

    And I want to retrieve filename, how can I do this? I know I can get the node value like this:

    //path/text()
    

    How can I get only the filename? (I know there is a concat() function, so maybe there is a split() function?)

  • Martin Honnen
    Martin Honnen over 13 years
    Yes, tokenize(/root/path, '\\')[last()] allows that but note that both replace and tokenize are XPath 2.0 and not available in XPath 1.0 so you need an XPath 2.0 implementation like Saxon 9 (saxon.sourceforge.net).
  • Alex Brown
    Alex Brown over 13 years
    Thanks, I couldn't work out whether last applied to dynamically generated collections.