Xquery 中的 XSLT 样式迷你转换?

XSLT-style mini transformation in Xquery?

目前在 Xquery 3.1(在 eXist 4.7 中)我收到 XML 如下所示的片段(来自 eXist 的 Lucene 全文搜索):

let $text :=

 <tei:text>
   <front>
     <tei:div>
        <tei:listBibl>
            <tei:bibl>There is some</tei:bibl>
            <tei:bibl>text in certain elements</tei:bibl>
        </tei:listBibl>
     </tei:div>
     <tei:div>
        <tei:listBibl>
            <tei:bibl>which are subject <exist:match>to</exist:match> a Lucene search</tei:bibl>
            <tei:bibl></tei:bibl>
        <tei:listBibl>
     </tei:div>
   <tei:front>
   <tei:body>
     <tei:p>and often produces</tei:p>
     <tei:p>a hit.</tei:p>
   <tei:body>
 <tei:text> 

目前,我让 Xquery 将此片段发送到 XSLT 样式表,以便将其转换为 HTML,如下所示:

<td>...elements which are subject <span class="search-hit">to</span> a Lucene search and often p...

样式表的工作是 return <exist:match/> 前后 30 个字符的文本,并将 <exist:match/> 的内容放入一个 span 中。每个转换只有一个 <exist:match/>

一切正常。然而,我想到这是一项非常小的工作,实际上只有一个元素的单一转换,其余的是一种字符串连接。因此我想知道这是否不能在 Xquery 中有效地完成。

在尝试这样做时,我似乎无法找到一种方法来处理 <exist:match/> 之前的字符串内容,然后是 <exist:match/> 之后的字符串内容。我的想法是,用伪代码输出如下结果:

let $textbefore := some function to get the text before <exist:match/>
let $textafter := some function to get text before <exist:match/>
return <td>...{$textbefore} 
        <span class="search-hit">
          {$text//exist:match/text()}
        </span> {$textafter}...</td>

与我现有的当前 Xquery -> XSLT 管道相比,在 Xquery 中这样做是否值得?

非常感谢。

我觉得可以这样

declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization";

declare namespace tei = "http://example.com/tei";
declare namespace exist = "http://example.com/exist";

declare option output:method 'html';

let $text :=

 <tei:text>
   <tei:front>
     <tei:div>
        <tei:listBibl>
            <tei:bibl>There is some</tei:bibl>
            <tei:bibl>text in certain elements</tei:bibl>
        </tei:listBibl>
     </tei:div>
     <tei:div>
        <tei:listBibl>
            <tei:bibl>which are subject <exist:match>to</exist:match> a Lucene search</tei:bibl>
            <tei:bibl></tei:bibl>
        </tei:listBibl>
     </tei:div>
   </tei:front>
   <tei:body>
     <tei:p>and often produces</tei:p>
     <tei:p>a hit.</tei:p>
   </tei:body>
 </tei:text> 
 , 
 $match := $text//exist:match,
 $text-before-all := normalize-space(string-join($match/preceding::text(), ' ')),
 $text-before := substring($text-before-all, string-length($text-before-all) - 30),
 $text-after := substring(normalize-space(string-join($match/following::text(), ' ')), 1, 30)
return 
 <td>...{$text-before} 
        <span class="search-hit">
          {$match/text()}
        </span> {$text-after}...</td>

这在 XQuery 中也不是真正的查询,而只是一些 XPath 选择加上一些可能昂贵的字符串连接和前后轴上的提取。