Hi, I got stuck with an XQuery, could you please help? I have data like this: <collection> <entry> <q>[text() contains text ('Johann' ftand 'Ballhorn') distance at most 5 words ordered][self::*:p or self::*:q]</q> <id>12345</id> <p>bey welchen die Verbesserungen durch Johann Ballhorn öfter vorkommen als man glauben sollte.</p> </entry> <entry>… </collection> All I want to get back is the <p> node with the content of the <q> node applied to <p> using ft:mark, i.e., the node with highlighting like this: <p>bey welchen die Verbesserungen durch <mark>Johann</mark> <mark>Ballhorn</mark> öfter vorkommen als man glauben sollte.</p> But I don't manage to call ft:mark with the correct parameters. I tried variants of this: for $i at $p in //entry let $q := $i/q return ft:mark($i $q) But this gives Expecting closing bracket for 'ft:mark(…' I think I have to use concat() in some way, but how? Thanks in advance Cerstin -- Dr. phil. Cerstin Mahlow Universität Basel Departement Sprach- und Literaturwissenschaften Fachbereich Deutsche Sprach- und Literaturwissenschaft Nadelberg 4 4051 Basel Schweiz Tel: +41 61 267 07 65 Fax: +41 61 267 34 40 Mail: cerstin.mahlow@unibas.ch Web: http://www.oldphras.net
Hi Cerstin, On 26.03.2013, at 16:07, Cerstin Elisabeth Mahlow <cerstin.mahlow@unibas.ch> wrote:
Hi,
I got stuck with an XQuery, could you please help?
I have data like this:
<collection> <entry> <q>[text() contains text ('Johann' ftand 'Ballhorn') distance at most 5 words ordered][self::*:p or self::*:q]</q> <id>12345</id> <p>bey welchen die Verbesserungen durch Johann Ballhorn öfter vorkommen als man glauben sollte.</p> </entry> <entry>… </collection>
All I want to get back is the <p> node with the content of the <q> node applied to <p> using ft:mark, i.e., the node with highlighting like this:
<p>bey welchen die Verbesserungen durch <mark>Johann</mark> <mark>Ballhorn</mark> öfter vorkommen als man glauben sollte.</p>
But I don't manage to call ft:mark with the correct parameters.
I tried variants of this:
for $i at $p in //entry let $q := $i/q return ft:mark($i $q)
But this gives
Expecting closing bracket for 'ft:mark(…'
I think I have to use concat() in some way, but how?
Thanks in advance
if I got you right you want to evaluate a query, such as ft:mark(<p>bey welchen die Verbesserungen durch Johann Ballhorn öfter vorkommen als man glauben sollte.</p>[./text() contains text ('Johann' ftand 'Ballhorn') distance at most 5 words ordered][self::*:p or self::*:q]) which you construct from your collection? <p>bey welchen ...</p> is a database node and <q>[text() contains text ('Johann' ... ]</q> holds a query predicate as string So you dynamically construct a query string that you like to evaluate? == Since ft:mark() operates on database nodes a simply typing ft:mark(<p>bey welchen die Verbesserungen durch Johann Ballhorn öfter vorkommen als man glauben sollte.</p>[./text() contains text ('Johann' ftand 'Ballhorn') distance at most 5 words ordered][self::*:p or self::*:q]) in BaseXGUi results in [BXDB0001] ft:mark(element p { ("bey welchen die Verbesserungen durch Johann Ballhorn öfter vorkommen als man glauben sollte.") }[text() contains text ("Johann" ftand "Ballhorn") ordered distance(0-5 word)][(self::*:p or self::*:q)]): database node expected. == However, we can create a database from your input data to set up a running example: db:create('cm', "<collection> <entry> <q>[text() contains text ('Johann' ftand 'Ballhorn') distance at most 5 words ordered][self::*:p or self::*:q]</q> <id>12345</id> <p>bey welchen die Verbesserungen durch Johann Ballhorn öfter vorkommen als man glauben sollte.</p> </entry> </collection>", "cm.xml") == Query: let $in := doc('cm') let $p := $in//p let $q := $in//q return ( $p, $q ) yields <p>bey welchen die Verbesserungen durch Johann Ballhorn öfter vorkommen als man glauben sollte.</p> <q>[text() contains text ('Johann' ftand 'Ballhorn') distance at most 5 words ordered][self::*:p or self::*:q]</q> == let $in := doc('cm') let $p := $in//p let $q := $in//q let $qs := concat('ft:mark($p', $q, ')') return $qs constructs the query string ft:mark($p[text() contains text ('Johann' ftand 'Ballhorn') distance at most 5 words ordered][self::*:p or self::*:q]) == let $in := doc('cm') let $p := $in//p let $q := $in//q let $qs := concat('ft:mark($p', $q, ')') return xquery:eval($qs) evaluates the query string ... aehh .. tries to evaluate the query string [XPST0008] Undefined variable $p. == http://docs.basex.org/wiki/XQuery_Module#xquery:eval shows how to pass a binding of into the query to be evaluated let $in := doc('cm') let $p := $in//p let $q := $in//q let $qs := concat('ft:mark($binding', $q, ')') let $bm := map{ '$binding' := $p } return xquery:eval($qs, $bm) constructs a query string ft:mark($binding[text() contains text ('Johann' ftand 'Ballhorn') distance at most 5 words ordered][self::*:p or self::*:q]) and a binding of $binding and results in <p>bey welchen die Verbesserungen durch <mark>Johann</mark> <mark>Ballhorn</mark> öfter vorkommen als man glauben sollte.</p> Which, I hope, is the result you wanted to achieve. All the best, Alex
Hi Alex, thanks for your answer! Am 26.03.2013 um 18:43 schrieb Alexander Holupirek <alexander.holupirek@uni-konstanz.de> :
if I got you right you want to evaluate a query, such as
ft:mark(<p>bey welchen die Verbesserungen durch Johann Ballhorn öfter vorkommen als man glauben sollte.</p>[./text() contains text ('Johann' ftand 'Ballhorn') distance at most 5 words ordered][self::*:p or self::*:q])
which you construct from your collection?
<p>bey welchen ...</p> is a database node and <q>[text() contains text ('Johann' ... ]</q> holds a query predicate as string
So you dynamically construct a query string that you like to evaluate?
I already have the complete query stored in the very same collection
==
Since ft:mark() operates on database nodes a simply typing
ft:mark(<p>bey welchen die Verbesserungen durch Johann Ballhorn öfter vorkommen als man glauben sollte.</p>[./text() contains text ('Johann' ftand 'Ballhorn') distance at most 5 words ordered][self::*:p or self::*:q])
in BaseXGUi results in
[BXDB0001] ft:mark(element p { ("bey welchen die Verbesserungen durch Johann Ballhorn öfter vorkommen als man glauben sollte.") }[text() contains text ("Johann" ftand "Ballhorn") ordered distance(0-5 word)][(self::*:p or self::*:q)]): database node expected.
Yes, I tried this :) […]
let $in := doc('cm') let $p := $in//p let $q := $in//q let $qs := concat('ft:mark($p', $q, ')') return xquery:eval($qs)
evaluates the query string ... aehh .. tries to evaluate the query string
[XPST0008] Undefined variable $p.
And also this.
http://docs.basex.org/wiki/XQuery_Module#xquery:eval shows how to pass a binding of into the query to be evaluated
let $in := doc('cm') let $p := $in//p let $q := $in//q let $qs := concat('ft:mark($binding', $q, ')') let $bm := map{ '$binding' := $p } return xquery:eval($qs, $bm)
constructs a query string
ft:mark($binding[text() contains text ('Johann' ftand 'Ballhorn') distance at most 5 words ordered][self::*:p or self::*:q]) and a binding of $binding and
results in
<p>bey welchen die Verbesserungen durch <mark>Johann</mark> <mark>Ballhorn</mark> öfter vorkommen als man glauben sollte.</p>
Which, I hope, is the result you wanted to achieve.
OK, I now have this: for $i at $p in //entry let $q := $i/q let $text := if ($i/p) then $i/p else $i/l let $ft := concat("ft:mark($binding", $q,")") let $bm := map{'$binding' := $text} return xquery:eval($ft, $bm) The if clause allows to skip the extension "[self::*:p or self::*:q]" of the query. Thanks for your help! Cerstin -- Dr. phil. Cerstin Mahlow Universität Basel Departement Sprach- und Literaturwissenschaften Fachbereich Deutsche Sprach- und Literaturwissenschaft Nadelberg 4 4051 Basel Schweiz Tel: +41 61 267 07 65 Fax: +41 61 267 34 40 Mail: cerstin.mahlow@unibas.ch Web: http://www.oldphras.net
participants (2)
-
Alexander Holupirek -
Cerstin Elisabeth Mahlow