Dynamic evaluation?

Wednesday, 26 February 2020 · 3 messages
BE
Ben Engbers26 Feb 2020 12:42 #
Hi, I want to declare a function that can operate on various elements of a record. It should be possible to pass the element-name as parameter to the function. I tried this:
declare function local:cloudWords(
  $Veld as xs:string
) as xs:string*
{
  let $base := collection('IncidentRemarks/Incidentsv')/csv/record
  let $txt := string-join( $base/$Veld/text(), " ")
  let $words := tokenize($txt,'(\s|[,.!:;]|[n][b][s][p][;])+')
  return ($words)
};

let $retValue := local:cloudWords("INC_RM")
return $retValue
But I get this error: [XPTY0019] text(): node expected, xs:string found: "INC_RM".
Should I use xquery:eval to transform "$base/$Veld/text()" into
"$base/INC_RM/text()"
Ben
MH
Martin Honnen26 Feb 2020 12:46 #
Quoted text · Ben Engbers · 28 lines
Am 26.02.2020 um 12:42 schrieb Ben Engbers: > Hi, > > I want to declare a function that can operate on various elements of a > record. It should be possible to pass the element-name as parameter to > the function. > > I tried this: > > declare function local:cloudWords( > $Veld as xs:string > ) as xs:string* > { > let $base := collection('IncidentRemarks/Incidentsv')/csv/record > let $txt := string-join( $base/$Veld/text(), " ") > let $words := tokenize($txt,'(\s|[,.!:;]|[n][b][s][p][;])+') > return ($words) > }; > > let $retValue := local:cloudWords("INC_RM") > return $retValue > > But I get this error: > [XPTY0019] text(): node expected, xs:string found: "INC_RM". > > Should I use xquery:eval to transform "$base/$Veld/text()" into > "$base/INC_RM/text()" >
For such simple cases with an element name it seems
   $base/*[local-name() = $Veld]
suffices.
CG
Christian Grün26 Feb 2020 13:04 #
…and to complement this: With the upcoming version 9.3.2 of BaseX, local-name() function calls in predicates will be optimized by the query compiler.
Your query…
*(
  declare function local:cloudWords(
    $Veld as xs:string
  ) as xs:string* {
    let $base := collection('IncidentRemarks/Incidentsv')/csv/record
    let $txt := string-join( $base/*[local-name() = $Veld]/text(), " ")
    return tokenize($txt,'(\s|[,.!:;]|[n][b][s][p][;])+')
  };

  let $retValue := local:cloudWords("INC_RM")
  return $retValue
…will then be rewritten to…
  tokenize(
    string-join(
      collection('IncidentRemarks/Incidentsv')/csv/record/INC_RM/text(), " "
    ),
    '(\s|[,.!:;]|[n][b][s][p][;])+'
  )
Cheers Christian PS: Are you sure that your INC_RM text strings still contain "nbsp" substrings?
Quoted text · Martin Honnen · 38 lines
On Wed, Feb 26, 2020 at 12:46 PM Martin Honnen <martin.honnen at gmx.de> wrote: > > Am 26.02.2020 um 12:42 schrieb Ben Engbers: > > Hi, > > > > I want to declare a function that can operate on various elements of a > > record. It should be possible to pass the element-name as parameter to > > the function. > > > > I tried this: > > > > declare function local:cloudWords( > > $Veld as xs:string > > ) as xs:string* > > { > > let $base := collection('IncidentRemarks/Incidentsv')/csv/record > > let $txt := string-join( $base/$Veld/text(), " ") > > let $words := tokenize($txt,'(\s|[,.!:;]|[n][b][s][p][;])+') > > return ($words) > > }; > > > > let $retValue := local:cloudWords("INC_RM") > > return $retValue > > > > But I get this error: > > [XPTY0019] text(): node expected, xs:string found: "INC_RM". > > > > Should I use xquery:eval to transform "$base/$Veld/text()" into > > "$base/INC_RM/text()" > > > For such simple cases with an element name it seems > > $base/*[local-name() = $Veld] > > > suffices. > >

⚡Generated with XQuery