xquerybasexxquery-3.1

Functx module and long strings with end of chars


I faced a problem with functx module dealing with strings with end of line characters. The following code should work (?)

declare %unit:test function test:substring-before-last() {

  let $title := 'Something
blah other'

  let $expected-title := 'Something
blah'

  return unit:assert-equals(functx:substring-before-last($title, ' other'),
    $expected-title)
};

However it gives a failure

"Something
blah" expected, "Something
blah other" returned.

Removing line breaking makes the test working. What I don't understand? :)

BR


Solution

  • I think the issue is in the definition or implementation of the functx function http://www.xqueryfunctions.com/xq/functx_substring-before-last.html:

    declare function functx:substring-before-last
      ( $arg as xs:string? ,
        $delim as xs:string )  as xs:string {
    
       if (matches($arg, functx:escape-for-regex($delim)))
       then replace($arg,
                concat('^(.*)', functx:escape-for-regex($delim),'.*'),
                '$1')
       else ''
     } ;
    

    and the regular expression dot . matching and the replace default "If the input string contains no substring that matches the regular expression, the result of the function is a single string identical to the input string."; if you add the flags m argument

    declare function functx:substring-before-last
      ( $arg as xs:string? ,
        $delim as xs:string )  as xs:string {
    
       if (matches($arg, functx:escape-for-regex($delim)))
       then replace($arg,
                concat('^(.*)', functx:escape-for-regex($delim),'.*'),
                '$1', 'm')
       else ''
     } ;
    

    you get the right match and replacement and comparison.