xquery:eval() - handling of &

Wednesday, 10 May 2023 · 3 messages · last reply 11 May 2023
AS
Andrew Sales10 May 2023 14:30 #

Hello,

The query

xquery:eval(
  'contains(.,"&")',
  map{'':<foo>&lt;&amp;&gt;</foo>}
)

results in: [XPST0003] Invalid entity: '&")...'.

I can get the expected result if I double-escape the entity:

'contains(.,"&amp;amp;")'

or wrap in a call to serialize:

serialize('contains(.,"&amp;")')

However, both

xquery:eval(
  'contains(.,"&lt;")',
  map{'':<foo>&lt;&amp;&gt;</foo>}
)

and

xquery:eval(
  'contains(.,"&gt;")',
  map{'':<foo>&lt;&amp;&gt;</foo>}
)

return true, as expected.

Is this a bug, or am I missing something?

Thanks, Andrew

CG
Christian Grün10 May 2023 22:34 #

Hi Andrew,

Quoted text · Andrew Sales · 3 lines
> 'contains(.,"&gt;")', > … > return true, as expected.

The difference is that < and > don’t have to be encoded if they are used in strings. You can write…

contains('', '<')

…but the following query is invalid:

contains('<', '&')

Quoted text · Andrew Sales · 2 lines
> I can get the expected result if I double-escape the entity: > 'contains(.,"&amp;amp;")'

You can use the string constructor syntax, it’s often better readable:

xquery:eval(
  ``[contains(., "&amp;")]``,
  map { '': <foo>{ ``[&<]`` }</foo> }
)

With recent versions of BaseX, you can also use simple backticks (that’s XQuery 4 syntax, it will be documented soon). The following queries are equivalent:

& ``[&]`` "&amp;"

Hope this helps, Christian

AS
Andrew Sales11 May 2023 11:05 #

Many thanks for explaining, Christian - that makes sense. Thank you also for 10.6!

All the best, Andrew

Quoted text · Christian Grün · 38 lines
On Wed, 10 May 2023 at 21:34, Christian Grün <christian.gruen at gmail.com> wrote: > Hi Andrew, > > > 'contains(.,"&gt;")', > > … > > return true, as expected. > > The difference is that < and > don’t have to be encoded if they are > used in strings. You can write… > > contains('', '<') > > …but the following query is invalid: > > contains('<', '&') > > > I can get the expected result if I double-escape the entity: > > 'contains(.,"&amp;amp;")' > > You can use the string constructor syntax, it’s often better readable: > > xquery:eval( > ``[contains(., "&amp;")]``, > map { '': <foo>{ ``[&<]`` }</foo> } > ) > > With recent versions of BaseX, you can also use simple backticks > (that’s XQuery 4 syntax, it will be documented soon). The following > queries are equivalent: > > `&` > ``[&]`` > "&amp;" > > Hope this helps, > Christian >

⚡Generated with XQuery