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 $retValueBut 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. > >
Written for BaseX 9.3. BaseX may have changed since: please check the current documentation.
⚡Generated with XQuery