BaseX 9.7 to BaseX 11: find a regex in an external file
Friday, 19 July 2024 · 3 messages
JM
Josselin Morvan19 Jul 2024 16:49 #
Hi Everyone,
I'm migrating a webapp from BaseX 9.7 to BaseX 11 and I'm having a problem with a wrapper function (just a function for adding content to an xml template file)
Basically, this function looks for nodes in a template.xml file that matche regex to update the content of this file. Here is a small example :
template.xml
<foo>
<bar>{content}</bar>
</foo>Query:
let $file := 'template.xml'
let $wrap := fn:doc($file)
let $regex := '\{(.+?)\}’ (: looking for something between curly braces :)
return
for $node in $data//*
where $node[fn:matches(text(), $regex)]
return $nodeThis function worked with BaseX 9.7, but returns an error with BaseX 11 : [XPTY0004] Item expected, sequence found: ("
 ", "
").
However, if I put the content of template.xml in a variable, it works (even with BaseX 11):
let $wrap :=
<foo>
<bar>{{content}}</bar> (: just escaped curly braces :)
</foo>
let $regex := '\{(.+?)\}'
return
for $node in $wrap//*
where $node[fn:matches(text(), $regex)]
return $node
(:<bar>{content}</bar>:)Do you have any idea of what I'm doing wrong or what I’m missing?
Thanks for your help!
Best,
Josselin
HR
Hans-Juergen Rennau19 Jul 2024 18:29 #
Hi Josselin,
you get an error because there are elements containing several text nodes, while the matches() function expects a single item. An element can contain several text nodes for various reasons, as for example mixed content, which is text with elements interspersed. In your case the input XML is "indented", which means it contains whitespace producing the pretty print effect. This whitespace is contained by text nodes, just like real data. In your example, <foo> contains <bar> as well as two whitespace-only text nodes. The error occurs only now because BaseX 9 by default stripped the pretty print text nodes, whereas now they are preserved. You can avoid the problem very simply by changing the "where" expression, so that it checks one text node at a time, like so:where $node[text()[
fn:matches(., $regex)]]Any $node will pass which contains at least one text node matching the regular expression.Cheers, Hans-Jürgen
Am Freitag, 19. Juli 2024 um 16:49:23 MESZ hat Josselin Morvan <morvan.josselin at gmail.com> Folgendes geschrieben:
Hi Everyone,
I'm migrating a webapp from BaseX 9.7 to BaseX 11 and I'm having a problem with a wrapper function (just a function for adding content to an xml template file) Basically, this function looks for nodes in a template.xml file that matche regex to update the content of this file. Here is a small example : template.xml<foo>
<bar>{content}</bar>
</foo>
Query:let $file := 'template.xml'
let $wrap := fn:doc($file)
let $regex := '\{(.+?)\}’ (: looking for something between curly braces :)return
for $node in $data//*
where $node[fn:matches(text(), $regex)]
return $node
This function worked with BaseX 9.7, but returns an error with BaseX 11 : [XPTY0004] Item expected, sequence found: ("
 ", "
").
However, if I put the content of template.xml in a variable, it works (even with BaseX 11):let $wrap :=
<foo>
<bar>{{content}}</bar> (: just escaped curly braces :)
</foo>
let $regex := '\{(.+?)\}'
return
for $node in $wrap//*
where $node[fn:matches(text(), $regex)]
return $node(:<bar>{content}</bar>:)
Do you have any idea of what I'm doing wrong or what I’m missing?
Thanks for your help!Best, JosselinJM
Josselin Morvan19 Jul 2024 19:42 #
Hi Hans-Juergen,
I missed that point! It works perfectly now. Thanks a lot!!
Best,
Josselin
Quoted text · Hans-Juergen Rennau · 58 lines
> Le 19 juil. 2024 à 18:29, Hans-Juergen Rennau <hrennau at yahoo.de> a écrit : > > Hi Josselin, > > you get an error because there are elements containing several text nodes, while the matches() function expects a single item. An element can contain several text nodes for various reasons, as for example mixed content, which is text with elements interspersed. In your case the input XML is "indented", which means it contains whitespace producing the pretty print effect. This whitespace is contained by text nodes, just like real data. In your example, <foo> contains <bar> as well as two whitespace-only text nodes. > > The error occurs only now because BaseX 9 by default stripped the pretty print text nodes, whereas now they are preserved. > > You can avoid the problem very simply by changing the "where" expression, so that it checks one text node at a time, like so: > where $node[text()[fn:matches(., $regex)]] > Any $node will pass which contains at least one text node matching the regular expression. > Cheers, > Hans-Jürgen > > Am Freitag, 19. Juli 2024 um 16:49:23 MESZ hat Josselin Morvan <morvan.josselin at gmail.com> Folgendes geschrieben: > > > Hi Everyone, > > I'm migrating a webapp from BaseX 9.7 to BaseX 11 and I'm having a problem with a wrapper function (just a function for adding content to an xml template file) > > Basically, this function looks for nodes in a template.xml file that matche regex to update the content of this file. Here is a small example : > > template.xml > <foo> > <bar>{content}</bar> > </foo> > > Query: > let $file := 'template.xml' > let $wrap := fn:doc($file) > let $regex := '\{(.+?)\}’ (: looking for something between curly braces :) > > return > for $node in $data//* > where $node[fn:matches(text(), $regex)] > return $node > > This function worked with BaseX 9.7, but returns an error with BaseX 11 : [XPTY0004] Item expected, sequence found: ("
 ", "
"). > > However, if I put the content of template.xml in a variable, it works (even with BaseX 11): > let $wrap := > <foo> > <bar>{{content}}</bar> (: just escaped curly braces :) > </foo> > let $regex := '\{(.+?)\}' > > return > for $node in $wrap//* > where $node[fn:matches(text(), $regex)] > return $node > (:<bar>{content}</bar>:) > > Do you have any idea of what I'm doing wrong or what I’m missing? > > Thanks for your help! > Best, > Josselin
Written for BaseX 11.1. BaseX may have changed since: please check the current documentation.
⚡Generated with XQuery