FontoXML / fontoxpath

A minimalistic XPath 3.1 implementation in pure JavaScript
MIT License
135 stars 17 forks source link

`matches` function doesn't work with flags argument #662

Open DetachHead opened 3 weeks ago

DetachHead commented 3 weeks ago

according to the xpath 3.0 spec, the matches function can take a third argument for regex flags.

however this doesn't seem to work in fontoxpath:

1: //tip[matches(., "^You", "m")]
         ^^^^^^^^^^^^^^^^^^^^^^^

Error: XPST0017: Function Q{http://www.w3.org/2005/xpath-functions}matches with arity of 3 not registered. Did you mean "Q{http://www.w3.org/2005/xpath-functions}matches (xs:string?, xs:string)"?
  at <functionCallExpr>:1:7 - 1:30
  at <pathExpr>:1:1 - 1:31

playground

DrRataplan commented 3 weeks ago

Hey!

Yep. That's not there yet. Seeing you're looking for it, would you maybe give it a go at implementing it. I can help out of course!

The relevant code is around here: https://github.com/FontoXML/fontoxpath/blob/master/src/expressions/functions/builtInFunctions_string.ts#L584

I would start with just the m flag, since that's what you need, and it does not seem like a difficult one to implement. I would recommend using the 3.1 spec though. I expect them to be the same but in the past I've seen subtle subtle differences between 3.0 and 3.1.

I'm afraid the place we actually need to implement it is in xspattern.js itself. XSD patterns themselves actually do not do flags, it's something bolted on in XPath/XQuery. But they do change the behaviour for those patterns. The ^ is basically changed from requiring a start to being an or over start and the position immediately after #x0A. and $ the position at the end, or the one right before a newline.

Kindest regards,

Martin

DetachHead commented 3 weeks ago

so it turns out the issue i had wasn't caused by a lack of the multiline flag. i was already using normalize-space which covers my use case, and the reason it wasn't matching was actually because the element contained some additional invisible text and i didn't notice