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 选择加上一些可能昂贵的字符串连接和前后轴上的提取。
目前在 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 选择加上一些可能昂贵的字符串连接和前后轴上的提取。