XQuery:Return 在 XML 文档中找到搜索词的次数
XQuery: Return how many times a search term was found in a XML document
我在 eXist 数据库中收集了两个 XML 文件(根据 TEI 标准标记并包含大量 <entry>
元素)。我使用 FLWOR 例程遍历文件,查找用户在表单中键入的搜索词 ($searchterm
) 并返回某些元素的内容。到目前为止,一切都很好。我现在想补充一点,但我不知道该怎么做:
我想计算 <form type="hyperlemma">
中有多少 <entry>
有 $searchterm
并打印它而不是 xxx
。如果 $searchterm
等于 "ангелъ",则数字将为 "3"。因为我需要在遍历集合之前打印该信息,所以我不知道我需要做什么。
有人能帮忙吗?由于我还是 XQuery 的新手,我的代码可能不是很漂亮,所以任何帮助我改进它的提示也非常感谢!
我的 XQuery:
xquery version "3.0";
declare namespace tei="http://www.tei-c.org/ns/1.0";
declare option exist:serialize "method=xhtml media-type=text/html";
declare variable $searchphrase := request:get-parameter("searchphrase", ());
declare variable $collection_path := "/db/apps/ex02/data";
<html>
<head>
<meta HTTP-EQUIV="Content-Type" content="text/html; charset=UTF-8"/>
<title>{$page-title}</title>
</head>
<body>
<h1>{$page-title}</h1>
<h2>Results</h2>
<p>Your input: "{$searchphrase}"</p>
<h3>Found xxx entries</h3>
{
for $file in collection($collection_path),
$hyperlemma in $file/(descendant::tei:entry | descendant::tei:cit)/tei:form[@type='hyperlemma']/tei:orth [ft:query(., $searchphrase)]
let $title := $hyperlemma/ancestor::*/tei:head
let $entry_number := $hyperlemma/ancestor::tei:entry[1]/@xml:id
let $lemma := $hyperlemma/ancestor::tei:entry/tei:form[@type='lemma']/tei:orth
return
<div>
{string($title)} ({data($entry_number)}):<br/>
<strong><font color="red">{string($lemma)}</font></strong><br/>
{
for $counterpart in $hyperlemma/ancestor::tei:entry/(tei:form[@type='lemma'] | tei:form[@type='variant'])/tei:cit/tei:form[@type='lemma']/tei:orth
return
<font color="green">    {string($counterpart)}<br/></font>
}
</div>
}
</body>
这些是两个 XML 文件的片段:
(A)
...
<text>
<head>Euch.</head>
<entry xml:id="pen-26">
<form type="hyperlemma" xml:lang="grc">
<orth>ἄγγελος</orth>
</form>
<form type="lemma" xml:lang="grc">
<orth>ἄγγελος</orth>
<cit type="counterpart" xml:lang="cu">
<form type="hyperlemma" xml:lang="cu">
<orth>ангелъ</orth>
</form>
<form type="lemma" xml:lang="cu">
<orth>аньꙉелъ</orth>
</form>
</cit>
</form>
</entry>
<entry xml:id="pen-336">
<form type="hyperlemma" xml:lang="grc">
<orth>ἀρχάγγελος</orth>
</form>
<form type="lemma" xml:lang="grc">
<orth>ἀρχάγγελος</orth>
<cit type="counterpart" xml:lang="cu">
<form type="hyperlemma" xml:lang="cu">
<orth>ангелъ</orth>
</form>
<form type="lemma" xml:lang="cu">
<orth>аньꙉелъ</orth>
</form>
</cit>
</form>
</entry>
</text>
...
(B)
...
<text>
<head>Syn.Tr. [1]</head>
<entry xml:id="tas-12">
<form type="hyperlemma" xml:lang="grc">
<orth>ἄγγελος</orth>
</form>
<form type="lemma" xml:lang="grc">
<orth>ἄγγελος</orth>
<cit type="counterpart" xml:lang="cu">
<form type="hyperlemma" xml:lang="cu">
<orth>ангелъ</orth>
</form>
<form type="lemma" xml:lang="cu">
<orth>ангєлъ</orth>
</form>
</cit>
<cit type="counterpart" xml:lang="cu">
<form type="hyperlemma" xml:lang="cu">
<orth>вѣстьникъ</orth>
</form>
<form type="lemma" xml:lang="cu">
<orth>вѣстьникъ</orth>
</form>
</cit>
</form>
</entry>
</text>
你只需要稍微重新组织查询和HTML输出,这样你就可以在执行查询之前输出你要输出的结果数和结果显示。您可以对结果调用 fn:count
以获取结果数。但是请注意,这里我们将两倍的东西打包到 $results 序列中,所以我们将它除以 2。例如:
xquery version "3.0";
declare namespace tei="http://www.tei-c.org/ns/1.0";
declare option exist:serialize "method=xhtml media-type=text/html";
declare variable $page-title := "SlaVaComp-DB";
declare variable $searchphrase := request:get-parameter("searchphrase", ());
declare variable $collection_path := "/db/apps/ex02/data";
<html>
<head>
<meta HTTP-EQUIV="Content-Type" content="text/html; charset=UTF-8"/>
<title>{$page-title}</title>
</head>
<body>
<h1>{$page-title}</h1>
{
let $results :=
for
$file in collection($collection_path),
$hyperlemma in $file/(descendant::tei:entry | descendant::tei:cit)/tei:form[@type='hyperlemma']/tei:orth [ft:query(., $searchphrase)]
return
($file, $hyperlemma)
return
let $count := count($results)
let $offsets :=
for $i in (0 to ($count div 2) cast as xs:integer - (if($count mod 2 eq 0)then 1 else 0))
return
2 * $i + 1
return
<div>
<h2>Results</h2>
<p>Your input: "{$searchphrase}"</p>
<h3>Found {$count div 2} entries</h3>
{
for $offset in $offsets
let $hyperlemma := $results[$offset + 1]
let $title := $hyperlemma/ancestor::*/tei:head
let $entry_number := $hyperlemma/ancestor::tei:entry[1]/@xml:id
let $lemma := $hyperlemma/ancestor::tei:entry/tei:form[@type='lemma']/tei:orth
return
<div>
{string($title)} ({data($entry_number)}):<br/>
<strong><font color="red">{string($lemma)}</font></strong><br/>
{
for $counterpart in $hyperlemma/ancestor::tei:entry/(tei:form[@type='lemma'] | tei:form[@type='variant'])/tei:cit/tei:form[@type='lemma']/tei:orth
return
<font color="green">    {string($counterpart)}<br/></font>
}
</div>
}
</div>
}
</body>
上面的查询有点复杂,因为我们将 $file
和 $hyperlemma
打包成一个序列,其中奇数偏移量是文件,偶数偏移量是超引理。
我注意到您没有在结果中使用 $file
,如果您不需要它,那么您的查询可以简化为:
xquery version "3.0";
declare namespace tei="http://www.tei-c.org/ns/1.0";
declare option exist:serialize "method=xhtml media-type=text/html";
declare variable $page-title := "SlaVaComp-DB";
declare variable $searchphrase := request:get-parameter("searchphrase", ());
declare variable $collection_path := "/db/apps/ex02/data";
<html>
<head>
<meta HTTP-EQUIV="Content-Type" content="text/html; charset=UTF-8"/>
<title>{$page-title}</title>
</head>
<body>
<h1>{$page-title}</h1>
{
let $hyperlemmas := collection($collection_path)/(descendant::tei:entry | descendant::tei:cit)/tei:form[@type='hyperlemma']/tei:orth [ft:query(., $searchphrase)]
return
<div>
<h2>Results</h2>
<p>Your input: "{$searchphrase}"</p>
<h3>Found {count($hyperlemmas)} entries</h3>
{
for $hyperlemma in $hyperlemmas
let $title := $hyperlemma/ancestor::*/tei:head
let $entry_number := $hyperlemma/ancestor::tei:entry[1]/@xml:id
let $lemma := $hyperlemma/ancestor::tei:entry/tei:form[@type='lemma']/tei:orth
return
<div>
{string($title)} ({data($entry_number)}):<br/>
<strong><font color="red">{string($lemma)}</font></strong><br/>
{
for $counterpart in $hyperlemma/ancestor::tei:entry/(tei:form[@type='lemma'] | tei:form[@type='variant'])/tei:cit/tei:form[@type='lemma']/tei:orth
return
<font color="green">    {string($counterpart)}<br/></font>
}
</div>
}
</div>
}
</body>
如果您想突出显示文本中各种关键字搜索匹配的位置,您可能也有兴趣阅读有关 KWIC 的内容:http://www.exist-db.org/exist/apps/doc/kwic.xml
我在 eXist 数据库中收集了两个 XML 文件(根据 TEI 标准标记并包含大量 <entry>
元素)。我使用 FLWOR 例程遍历文件,查找用户在表单中键入的搜索词 ($searchterm
) 并返回某些元素的内容。到目前为止,一切都很好。我现在想补充一点,但我不知道该怎么做:
我想计算 <form type="hyperlemma">
中有多少 <entry>
有 $searchterm
并打印它而不是 xxx
。如果 $searchterm
等于 "ангелъ",则数字将为 "3"。因为我需要在遍历集合之前打印该信息,所以我不知道我需要做什么。
有人能帮忙吗?由于我还是 XQuery 的新手,我的代码可能不是很漂亮,所以任何帮助我改进它的提示也非常感谢!
我的 XQuery:
xquery version "3.0";
declare namespace tei="http://www.tei-c.org/ns/1.0";
declare option exist:serialize "method=xhtml media-type=text/html";
declare variable $searchphrase := request:get-parameter("searchphrase", ());
declare variable $collection_path := "/db/apps/ex02/data";
<html>
<head>
<meta HTTP-EQUIV="Content-Type" content="text/html; charset=UTF-8"/>
<title>{$page-title}</title>
</head>
<body>
<h1>{$page-title}</h1>
<h2>Results</h2>
<p>Your input: "{$searchphrase}"</p>
<h3>Found xxx entries</h3>
{
for $file in collection($collection_path),
$hyperlemma in $file/(descendant::tei:entry | descendant::tei:cit)/tei:form[@type='hyperlemma']/tei:orth [ft:query(., $searchphrase)]
let $title := $hyperlemma/ancestor::*/tei:head
let $entry_number := $hyperlemma/ancestor::tei:entry[1]/@xml:id
let $lemma := $hyperlemma/ancestor::tei:entry/tei:form[@type='lemma']/tei:orth
return
<div>
{string($title)} ({data($entry_number)}):<br/>
<strong><font color="red">{string($lemma)}</font></strong><br/>
{
for $counterpart in $hyperlemma/ancestor::tei:entry/(tei:form[@type='lemma'] | tei:form[@type='variant'])/tei:cit/tei:form[@type='lemma']/tei:orth
return
<font color="green">    {string($counterpart)}<br/></font>
}
</div>
}
</body>
这些是两个 XML 文件的片段:
(A)
...
<text>
<head>Euch.</head>
<entry xml:id="pen-26">
<form type="hyperlemma" xml:lang="grc">
<orth>ἄγγελος</orth>
</form>
<form type="lemma" xml:lang="grc">
<orth>ἄγγελος</orth>
<cit type="counterpart" xml:lang="cu">
<form type="hyperlemma" xml:lang="cu">
<orth>ангелъ</orth>
</form>
<form type="lemma" xml:lang="cu">
<orth>аньꙉелъ</orth>
</form>
</cit>
</form>
</entry>
<entry xml:id="pen-336">
<form type="hyperlemma" xml:lang="grc">
<orth>ἀρχάγγελος</orth>
</form>
<form type="lemma" xml:lang="grc">
<orth>ἀρχάγγελος</orth>
<cit type="counterpart" xml:lang="cu">
<form type="hyperlemma" xml:lang="cu">
<orth>ангелъ</orth>
</form>
<form type="lemma" xml:lang="cu">
<orth>аньꙉелъ</orth>
</form>
</cit>
</form>
</entry>
</text>
...
(B)
...
<text>
<head>Syn.Tr. [1]</head>
<entry xml:id="tas-12">
<form type="hyperlemma" xml:lang="grc">
<orth>ἄγγελος</orth>
</form>
<form type="lemma" xml:lang="grc">
<orth>ἄγγελος</orth>
<cit type="counterpart" xml:lang="cu">
<form type="hyperlemma" xml:lang="cu">
<orth>ангелъ</orth>
</form>
<form type="lemma" xml:lang="cu">
<orth>ангєлъ</orth>
</form>
</cit>
<cit type="counterpart" xml:lang="cu">
<form type="hyperlemma" xml:lang="cu">
<orth>вѣстьникъ</orth>
</form>
<form type="lemma" xml:lang="cu">
<orth>вѣстьникъ</orth>
</form>
</cit>
</form>
</entry>
</text>
你只需要稍微重新组织查询和HTML输出,这样你就可以在执行查询之前输出你要输出的结果数和结果显示。您可以对结果调用 fn:count
以获取结果数。但是请注意,这里我们将两倍的东西打包到 $results 序列中,所以我们将它除以 2。例如:
xquery version "3.0";
declare namespace tei="http://www.tei-c.org/ns/1.0";
declare option exist:serialize "method=xhtml media-type=text/html";
declare variable $page-title := "SlaVaComp-DB";
declare variable $searchphrase := request:get-parameter("searchphrase", ());
declare variable $collection_path := "/db/apps/ex02/data";
<html>
<head>
<meta HTTP-EQUIV="Content-Type" content="text/html; charset=UTF-8"/>
<title>{$page-title}</title>
</head>
<body>
<h1>{$page-title}</h1>
{
let $results :=
for
$file in collection($collection_path),
$hyperlemma in $file/(descendant::tei:entry | descendant::tei:cit)/tei:form[@type='hyperlemma']/tei:orth [ft:query(., $searchphrase)]
return
($file, $hyperlemma)
return
let $count := count($results)
let $offsets :=
for $i in (0 to ($count div 2) cast as xs:integer - (if($count mod 2 eq 0)then 1 else 0))
return
2 * $i + 1
return
<div>
<h2>Results</h2>
<p>Your input: "{$searchphrase}"</p>
<h3>Found {$count div 2} entries</h3>
{
for $offset in $offsets
let $hyperlemma := $results[$offset + 1]
let $title := $hyperlemma/ancestor::*/tei:head
let $entry_number := $hyperlemma/ancestor::tei:entry[1]/@xml:id
let $lemma := $hyperlemma/ancestor::tei:entry/tei:form[@type='lemma']/tei:orth
return
<div>
{string($title)} ({data($entry_number)}):<br/>
<strong><font color="red">{string($lemma)}</font></strong><br/>
{
for $counterpart in $hyperlemma/ancestor::tei:entry/(tei:form[@type='lemma'] | tei:form[@type='variant'])/tei:cit/tei:form[@type='lemma']/tei:orth
return
<font color="green">    {string($counterpart)}<br/></font>
}
</div>
}
</div>
}
</body>
上面的查询有点复杂,因为我们将 $file
和 $hyperlemma
打包成一个序列,其中奇数偏移量是文件,偶数偏移量是超引理。
我注意到您没有在结果中使用 $file
,如果您不需要它,那么您的查询可以简化为:
xquery version "3.0";
declare namespace tei="http://www.tei-c.org/ns/1.0";
declare option exist:serialize "method=xhtml media-type=text/html";
declare variable $page-title := "SlaVaComp-DB";
declare variable $searchphrase := request:get-parameter("searchphrase", ());
declare variable $collection_path := "/db/apps/ex02/data";
<html>
<head>
<meta HTTP-EQUIV="Content-Type" content="text/html; charset=UTF-8"/>
<title>{$page-title}</title>
</head>
<body>
<h1>{$page-title}</h1>
{
let $hyperlemmas := collection($collection_path)/(descendant::tei:entry | descendant::tei:cit)/tei:form[@type='hyperlemma']/tei:orth [ft:query(., $searchphrase)]
return
<div>
<h2>Results</h2>
<p>Your input: "{$searchphrase}"</p>
<h3>Found {count($hyperlemmas)} entries</h3>
{
for $hyperlemma in $hyperlemmas
let $title := $hyperlemma/ancestor::*/tei:head
let $entry_number := $hyperlemma/ancestor::tei:entry[1]/@xml:id
let $lemma := $hyperlemma/ancestor::tei:entry/tei:form[@type='lemma']/tei:orth
return
<div>
{string($title)} ({data($entry_number)}):<br/>
<strong><font color="red">{string($lemma)}</font></strong><br/>
{
for $counterpart in $hyperlemma/ancestor::tei:entry/(tei:form[@type='lemma'] | tei:form[@type='variant'])/tei:cit/tei:form[@type='lemma']/tei:orth
return
<font color="green">    {string($counterpart)}<br/></font>
}
</div>
}
</div>
}
</body>
如果您想突出显示文本中各种关键字搜索匹配的位置,您可能也有兴趣阅读有关 KWIC 的内容:http://www.exist-db.org/exist/apps/doc/kwic.xml