xquery help
Tuesday, 26 March 2013 · 3 messages
CM
Cerstin Elisabeth Mahlow26 Mar 2013 16:07 #
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 at unibas.ch
Web: http://www.oldphras.net
AH
Alexander Holupirek26 Mar 2013 18:43 #
Hi Cerstin,
Quoted text · Cerstin Elisabeth Mahlow · 35 lines
On 26.03.2013, at 16:07, Cerstin Elisabeth Mahlow <cerstin.mahlow at 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 stringSo you dynamically construct a query string that you like to evaluate?
==
Since
ft:mark() operates on database nodes a simply typingft: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
$qsconstructs 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 andresults 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
CM
Cerstin Elisabeth Mahlow26 Mar 2013 20:09 #
Hi Alex,
thanks for your answer!
Am 26.03.2013 um 18:43 schrieb Alexander Holupirek <alexander.holupirek at uni-konstanz.de> :
Quoted text · Alexander Holupirek · 11 lines
> > 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
Quoted text · Alexander Holupirek · 9 lines
> == > > 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 :)
[…]
Quoted text · Alexander Holupirek · 10 lines
> 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.
Quoted text · Alexander Holupirek · 21 lines
> > 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 at unibas.ch
Web: http://www.oldphras.net
Written for BaseX 7.6. BaseX may have changed since: please check the current documentation.
⚡Generated with XQuery