comparison software/eXist/webapp/mpdl/_stuff/oxygen-projects/monte-project/archimedes-xml-fragment.xsl @ 7:5589d865af7a

Erstellung XQL/XSL Applikation
author Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
date Tue, 08 Feb 2011 15:16:46 +0100
parents
children
comparison
equal deleted inserted replaced
6:2396a569e446 7:5589d865af7a
1 <xsl:stylesheet version="2.0"
2 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
3 xmlns:xlink="http://www.w3.org/1999/xlink"
4 xmlns:xs="http://www.w3.org/2001/XMLSchema"
5 xmlns:functx="http://www.functx.com"
6 xmlns:text="http://www.mpiwg-berlin.mpg.de/ns/mpdl/text">
7
8 <xsl:output method="html"/>
9
10 <!-- siehe unter http://www.xsltfunctions.com -->
11 <xsl:function name="functx:contains-any-of" as="xs:boolean">
12 <xsl:param name="arg" as="xs:string?"/>
13 <xsl:param name="searchStrings" as="xs:string*"/>
14 <xsl:sequence select="some $searchString in $searchStrings satisfies contains($arg,$searchString)"/>
15 </xsl:function>
16
17 <!-- Highlight all term occurrences for the fulltext query. It recognizes the first occorrence and then does
18 this function recursive with the first substring before the first term cut off.
19 Result is a sequence of text and highlight nodes:
20 Example:
21 LE<lb></lb>
22 <span ...>MECHANICHE</span>
23 ...<lb></lb>
24 ...<lb></lb>
25 <span ...>MECHANICHE</span>
26 ...<lb></lb>
27 ...<lb></lb>
28 ...
29 -->
30 <xsl:function name="text:highlight">
31 <xsl:param name="inputString" />
32 <xsl:param name="luceneQuery" as="xs:string" />
33 <xsl:param name="mode" as="xs:string" />
34 <!-- Translation from Lucene fulltext query to text query -->
35 <xsl:variable name="textQuery">
36 <xsl:choose>
37 <xsl:when test="$mode = 'phrase'">
38 <xsl:value-of select="substring-before(substring-after($luceneQuery, '&quot;'), '&quot;')"/>
39 </xsl:when>
40 <xsl:when test="$mode = 'fakeWord'">
41 <xsl:value-of select="$luceneQuery"/>
42 </xsl:when>
43 <xsl:when test="$mode = 'word'">
44 <xsl:value-of select="$luceneQuery"/>
45 </xsl:when>
46 <xsl:otherwise><xsl:value-of select="''"/></xsl:otherwise>
47 </xsl:choose>
48 </xsl:variable>
49 <!-- Word delimiter: not tested yet -->
50 <xsl:variable name="wordDelimRegExpr" select="'[\s\(\)\[\]\.\\\{\}\$\^\+\?\!\* ยง%:,;=/]+'"/> <!-- TODO: bol, eol, ", &, <, > -->
51 <!-- Recognizes the beginning of the line with ^ and the substring up to the query term -->
52 <xsl:variable name="queryRegExprSubstringBefore">
53 <xsl:choose>
54 <xsl:when test="$mode = 'phrase'">
55 <xsl:value-of select="concat('^.*?', $textQuery)"/>
56 </xsl:when>
57 <xsl:when test="$mode = 'fakeWord'">
58 <xsl:value-of select="concat('^.*?', $textQuery)"/>
59 </xsl:when>
60 <xsl:when test="$mode = 'word'">
61 <xsl:value-of select="concat('^.*?', $wordDelimRegExpr, $textQuery, '(', $wordDelimRegExpr, ')')"/>
62 </xsl:when>
63 <xsl:otherwise><xsl:value-of select="''"/></xsl:otherwise>
64 </xsl:choose>
65 </xsl:variable>
66 <!-- Recognizes the substring after the query term -->
67 <xsl:variable name="queryRegExprSubstringAfter">
68 <xsl:choose>
69 <xsl:when test="$mode = 'phrase'">
70 <xsl:value-of select="concat($textQuery, '.*')"/>
71 </xsl:when>
72 <xsl:when test="$mode = 'fakeWord'">
73 <xsl:value-of select="concat($textQuery, '.*')"/>
74 </xsl:when>
75 <xsl:when test="$mode = 'word'">
76 <xsl:value-of select="concat('(', $wordDelimRegExpr, ')', $textQuery, $wordDelimRegExpr, '.*')"/>
77 </xsl:when>
78 <xsl:otherwise><xsl:value-of select="''"/></xsl:otherwise>
79 </xsl:choose>
80 </xsl:variable>
81 <!-- Deletes the substring up to the query term -->
82 <xsl:variable name="substringBefore" select="replace($inputString, $queryRegExprSubstringAfter, '$1', 'i')"/>
83 <!-- Deletes the substring after the query term -->
84 <xsl:variable name="substringAfter" select="replace($inputString, $queryRegExprSubstringBefore, '$1', 'i')"/>
85 <xsl:choose>
86 <xsl:when test="matches($inputString, $queryRegExprSubstringBefore, 'i')">
87 <!-- Prints the original part of the substring up to the first occurrence of the query term -->
88 <xsl:value-of select="$substringBefore"/>
89 <!-- Highlight the query term -->
90 <xsl:variable name="matchQueryTermRegExpr">
91 <xsl:choose>
92 <xsl:when test="$mode = 'phrase'">
93 <xsl:value-of select="concat('^.*?', '(', $textQuery, ')', '.*')"/>
94 </xsl:when>
95 <xsl:when test="$mode = 'fakeWord'">
96 <xsl:value-of select="concat('^.*?', '(', $textQuery, ')', '.*')"/>
97 </xsl:when>
98 <xsl:when test="$mode = 'word'">
99 <xsl:value-of select="concat('^.*?', $wordDelimRegExpr, '(', $textQuery, ')', $wordDelimRegExpr, '.*')"/>
100 </xsl:when>
101 <xsl:otherwise><xsl:value-of select="''"/></xsl:otherwise>
102 </xsl:choose>
103 </xsl:variable>
104 <xsl:variable name="matchQueryTerm" select="replace($inputString, $matchQueryTermRegExpr, '$1', 'i')"/>
105 <span style="background-color: yellow;">
106 <xsl:value-of select="$matchQueryTerm"/>
107 </span>
108 <!-- Recursive call of this function with the substring after the first occurrence of the term: further occurrences of the query
109 term -->
110 <xsl:sequence select="text:highlight($substringAfter, $luceneQuery, $mode)"/>
111 </xsl:when>
112 <!-- if no occurrence of the query term could be found the whole string is printed -->
113 <xsl:otherwise>
114 <xsl:value-of select="$inputString"/>
115 </xsl:otherwise>
116 </xsl:choose>
117 </xsl:function>
118
119 <!--
120 <xsl:function name="text:limitHighligthedString">
121 <xsl:param name="inputString" />
122 <xsl:param name="countChar" as="xs:integer"/>
123 <xsl:variable name="substringBeforeHighlight" select="substring-before($inputString, '&lt;span')"/>
124 <xsl:variable name="substringAfterHighlight" select="substring-after($inputString, '&lt;span&gt;>')"/>
125 <xsl:variable name="result">
126 ... <xsl:value-of select="substring($substringBeforeHighlight, string-length($substringBeforeHighlight) - $countChar)"/><span style="background-color: yellow;"><xsl:value-of select="' BlaBla '"/></span><xsl:value-of select="substring($substringAfterHighlight, 0, $countChar)"/> ...
127 </xsl:variable>
128 <xsl:sequence select="$result"/>
129 </xsl:function>
130 -->
131
132 <xsl:function name="text:limitHighligthedString">
133 <xsl:param name="inputSequence" as="node()*"/>
134 <xsl:param name="countChar" as="xs:integer"/>
135 <xsl:variable name="before" select="$inputSequence[1]"/>
136 <xsl:variable name="beforeLimited" select="substring($before, string-length($before) - $countChar)"/>
137 <xsl:variable name="firstSpan" select="$inputSequence[2]"/>
138 <xsl:variable name="after" select="$inputSequence[position() > 2]"/>
139 <xsl:variable name="afterLimited" select="substring($after, 0, $countChar)"/>
140 <xsl:variable name="result">
141 ... <xsl:sequence select="$before"/><xsl:sequence select="$firstSpan"/><xsl:sequence select="$after"/> ...
142 </xsl:variable>
143 <xsl:sequence select="$result"/>
144 </xsl:function>
145
146 <xsl:variable name="ftQueryName" select="/result/ft-query/name"/>
147 <xsl:variable name="ftQueryStr" select="concat('&amp;', 'ft-query=', $ftQueryName)"/>
148 <xsl:variable name="ftQueryMode">
149 <xsl:choose>
150 <xsl:when test="matches($ftQueryName, concat('&quot;', '.*', '&quot;'))">
151 <xsl:value-of select="'phrase'"/>
152 </xsl:when>
153 <xsl:when test="string-length($ftQueryName) = 0">
154 <xsl:value-of select="'false'"/>
155 </xsl:when>
156 <!-- Because there are problems in recognizing words (in mode word) this fake mode is used (same as phrase mode) -->
157 <xsl:otherwise><xsl:value-of select="'fakeWord'"/></xsl:otherwise>
158 </xsl:choose>
159 </xsl:variable>
160 <xsl:variable name="ftQueryValue">
161 <xsl:choose>
162 <xsl:when test="/result/ft-query[node()]"><xsl:value-of select="$ftQueryStr"/></xsl:when>
163 <xsl:otherwise><xsl:value-of select="''"/></xsl:otherwise>
164 </xsl:choose>
165 </xsl:variable>
166
167 <xsl:template match="result">
168 <html><body>
169 <xsl:variable name="ft-query-name" select="/result/ft-query/name"/>
170 <xsl:for-each select="document-description">
171 <h2>
172 <xsl:for-each select="info">
173 <xsl:value-of select="author"/>.
174 <xsl:value-of select="title"/>.
175 <xsl:value-of select="place"/>,
176 <xsl:value-of select="date"/>
177 </xsl:for-each>
178 </h2>
179 </xsl:for-each>
180 <form action="" method="get"></form>
181 <xsl:for-each select="page">
182 <xsl:variable name="documentName" select="/result/document-description/document-name"/>
183 <xsl:variable name="countPages" select="/result/document-description/count-pages"/>
184 <xsl:variable name="number" select="number(number)"/>
185 <xsl:variable name="documentValue" select="concat('document=', $documentName)"/>
186 <xsl:variable name="pnValue" select="concat('pn=', $number)"/>
187 <xsl:variable name="modeImageValue" select="concat('mode=', 'image')"/>
188 <xsl:variable name="modeXmlValue" select="concat('mode=', 'xml')"/>
189 <xsl:variable name="modeTextValue" select="concat('mode=', 'text')"/>
190 <xsl:variable name="imageLink" select="concat($documentValue, '&amp;', $pnValue, '&amp;', $modeImageValue, $ftQueryValue)"/>
191 <xsl:variable name="textLink" select="concat($documentValue, '&amp;', $pnValue, '&amp;', $modeTextValue, $ftQueryValue)"/>
192 <xsl:variable name="xmlLink" select="concat($documentValue, '&amp;', $pnValue, '&amp;', $modeXmlValue, $ftQueryValue)"/>
193 <table width="100%">
194 <colgroup>
195 <col width="30%"/>
196 <col width="70%"/>
197 </colgroup>
198 <tr>
199 <td align="left" nowrap="true">
200 [<a href="?{$textLink}">Text</a>]
201 [<a href="?{$imageLink}">Image</a>]
202 [XML]
203 </td>
204 <td align="right" nowrap="true">
205 <td>
206 <xsl:choose>
207 <xsl:when test="$number &gt; 1">
208 <a href="?{$documentValue}&amp;pn={$number - 1}&amp;{$modeXmlValue}{$ftQueryValue}"><img src="images/left.gif" alt="page-down" border="0"/></a>
209 </xsl:when>
210 <xsl:otherwise>
211 <a href="?{$xmlLink}"><img src="images/left.gif" alt="page-down" border="0"/></a>
212 </xsl:otherwise>
213 </xsl:choose>
214 </td>
215 <td nowrap="true">
216 <xsl:value-of select="$number"/> / <xsl:value-of select="$countPages"/>
217 </td>
218 <td>
219 <xsl:choose>
220 <xsl:when test="$number &lt; $countPages">
221 <a href="?{$documentValue}&amp;pn={$number + 1}&amp;{$modeXmlValue}{$ftQueryValue}"><img src="images/right.gif" alt="page-up" border="0"/></a>
222 </xsl:when>
223 <xsl:otherwise>
224 <a href="?{$xmlLink}"><img src="images/right.gif" alt="page-down" border="0"/></a>
225 </xsl:otherwise>
226 </xsl:choose>
227 </td>
228 <td nowrap="true">
229 <input type="hidden" name="document" value="{$documentName}"/>
230 Page: <input type="text" size="3" name="pn" value="{$number}"/>
231 <input type="hidden" name="mode" value="xml"/>
232 <xsl:if test="/result/ft-query[node()]">
233 <input type="hidden" name="ft-query" value="{$ftQueryName}"/>
234 </xsl:if>
235 </td>
236 </td>
237 </tr>
238 </table>
239 <hr/>
240 <table align="middle" width="100%">
241 <colgroup>
242 <col width="70%"/>
243 <col width="30%"/>
244 </colgroup>
245 <tr>
246 <td align="left" valign="top">
247 <xsl:for-each select="content">
248 <xsl:apply-templates/>
249 </xsl:for-each>
250 </td>
251 <xsl:if test="$ftQueryValue!=''">
252 <td align="left" valign="top">
253 <b><xsl:value-of select="/result/ft-query/result/size"/> Hits: "<xsl:value-of select="$ftQueryName"/>"</b>
254 <ol>
255 <xsl:for-each select="/result/ft-query/result/hits/hit">
256 <li>
257 <xsl:variable name="hitPN" select="pn"/>
258 <xsl:variable name="hitPosOfS" select="pos-of-s"/>
259 <a href="?{$documentValue}&amp;pn={$hitPN}&amp;{$modeXmlValue}{$ftQueryValue}">Page <xsl:value-of select="$hitPN"/>, Sentence <xsl:value-of select="$hitPosOfS"/></a>:<br></br>
260 <!-- Highlight the query terms in each hit -->
261 <xsl:variable name="highlightedSentenceSeq" select="text:highlight(s, $ftQueryName, $ftQueryMode)"/>
262 <xsl:sequence select="text:limitHighligthedString($highlightedSentenceSeq, 100)"/>
263 </li>
264 </xsl:for-each>
265 </ol>
266 </td>
267 </xsl:if>
268 </tr>
269 </table>
270 <hr/>
271 Elapsed time: <xsl:value-of select="/result/document-description/performance"/> ms, Back to <a href="query.xql">query page</a>, see the <a href="page-query-result.xql?_source=yes">XQuery source</a> and <a href="/exist/rest/db/xsl/archimedes-xml-fragment.xsl?_source=yes">XSL source</a> of this page
272 <br/>
273 [<a href="page-query-result.xql?{$xmlLink}">fast mechanism (file system search)</a>] [<a href="page-query-result-old.xql?{$xmlLink}">slower mechanism (XQL search)</a>]
274 </xsl:for-each>
275 </body></html>
276 </xsl:template>
277
278
279 <xsl:template match="attribute()|element()|text()|comment()|processing-instruction()">
280 <xsl:copy>
281 <xsl:apply-templates select="attribute()|element()|text()|comment()|processing-instruction()"/>
282 </xsl:copy>
283 </xsl:template>
284
285 <xsl:template match="element()|text()|comment()|processing-instruction()">
286 <xsl:variable name="elementName" select="name()"/>
287 <span style="color: brown;">&lt;<xsl:value-of select="$elementName"/><xsl:apply-templates select="attribute()"/>&gt;</span>
288 <xsl:apply-templates select="element()|text()|comment()|processing-instruction()"/>
289 <span style="color: brown;">&lt;/<xsl:value-of select="$elementName"/>&gt;</span>
290 <br/>
291 </xsl:template>
292
293 <xsl:template match="attribute()">
294 <xsl:variable name="attributeName" select="name()"/>
295 <xsl:text> </xsl:text><xsl:value-of select="$attributeName"/>=<xsl:value-of select="."/>
296 <xsl:apply-templates select="attribute()"/>
297 </xsl:template>
298
299 <!-- If ft-query is set then highlight all term occurrences for the fulltext query else show the text -->
300 <xsl:template match="text()">
301 <xsl:choose>
302 <xsl:when test="$ftQueryMode != 'false'">
303 <xsl:sequence select="text:highlight(., $ftQueryName, $ftQueryMode)"/>
304 </xsl:when>
305 <xsl:otherwise>
306 <xsl:value-of select="."/>
307 </xsl:otherwise>
308 </xsl:choose>
309 </xsl:template>
310
311 </xsl:stylesheet>