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">&#160;&#160;&#160;&#160;{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">&#160;&#160;&#160;&#160;{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">&#160;&#160;&#160;&#160;{string($counterpart)}<br/></font>
                    }
                    </div>
            }
        </div>
}
</body>

如果您想突出显示文本中各种关键字搜索匹配的位置,您可能也有兴趣阅读有关 KWIC 的内容:http://www.exist-db.org/exist/apps/doc/kwic.xml