diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/webapp/mpdl/_stuff/oxygen-projects/monte-project/archimedes-xml-fragment.xsl	Tue Feb 08 15:16:46 2011 +0100
@@ -0,0 +1,311 @@
+<xsl:stylesheet version="2.0" 
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns:functx="http://www.functx.com"
+ xmlns:text="http://www.mpiwg-berlin.mpg.de/ns/mpdl/text">
+
+<xsl:output method="html"/>
+
+<!-- siehe unter http://www.xsltfunctions.com     -->
+<xsl:function name="functx:contains-any-of" as="xs:boolean">
+  <xsl:param name="arg" as="xs:string?"/> 
+  <xsl:param name="searchStrings" as="xs:string*"/> 
+  <xsl:sequence select="some $searchString in $searchStrings satisfies contains($arg,$searchString)"/>
+</xsl:function>
+
+<!-- Highlight all term occurrences for the fulltext query. It recognizes the first occorrence and then does 
+this function recursive with the first substring before the first term cut off.
+Result is a sequence of text and highlight nodes:
+Example:
+LE<lb></lb>
+<span ...>MECHANICHE</span>
+...<lb></lb>
+...<lb></lb>
+<span ...>MECHANICHE</span>
+...<lb></lb>
+...<lb></lb>
+...
+ -->
+<xsl:function name="text:highlight">
+  <xsl:param name="inputString" />
+  <xsl:param name="luceneQuery" as="xs:string" />
+  <xsl:param name="mode" as="xs:string" />
+  <!-- Translation from Lucene fulltext query to text query  -->  
+  <xsl:variable name="textQuery">
+    <xsl:choose>
+      <xsl:when test="$mode = 'phrase'">
+        <xsl:value-of select="substring-before(substring-after($luceneQuery, '&quot;'), '&quot;')"/>
+      </xsl:when>
+      <xsl:when test="$mode = 'fakeWord'">
+        <xsl:value-of select="$luceneQuery"/>
+      </xsl:when>
+      <xsl:when test="$mode = 'word'">
+        <xsl:value-of select="$luceneQuery"/>
+      </xsl:when>
+      <xsl:otherwise><xsl:value-of select="''"/></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <!-- Word delimiter: not tested yet -->
+  <xsl:variable name="wordDelimRegExpr" select="'[\s\(\)\[\]\.\\\{\}\$\^\+\?\!\* ยง%:,;=/]+'"/>   <!-- TODO: bol, eol, ", &, <, >    --> 
+  <!-- Recognizes the beginning of the line with ^ and the substring up to the query term -->
+  <xsl:variable name="queryRegExprSubstringBefore">
+    <xsl:choose>
+      <xsl:when test="$mode = 'phrase'">
+        <xsl:value-of select="concat('^.*?', $textQuery)"/>
+      </xsl:when>
+      <xsl:when test="$mode = 'fakeWord'">
+        <xsl:value-of select="concat('^.*?', $textQuery)"/>
+      </xsl:when>
+      <xsl:when test="$mode = 'word'">
+        <xsl:value-of select="concat('^.*?', $wordDelimRegExpr, $textQuery, '(',  $wordDelimRegExpr, ')')"/>
+      </xsl:when>
+      <xsl:otherwise><xsl:value-of select="''"/></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <!-- Recognizes the substring after the query term -->
+  <xsl:variable name="queryRegExprSubstringAfter">
+    <xsl:choose>
+      <xsl:when test="$mode = 'phrase'">
+        <xsl:value-of select="concat($textQuery, '.*')"/>
+      </xsl:when>
+      <xsl:when test="$mode = 'fakeWord'">
+        <xsl:value-of select="concat($textQuery, '.*')"/>
+      </xsl:when>
+      <xsl:when test="$mode = 'word'">
+        <xsl:value-of select="concat('(', $wordDelimRegExpr, ')', $textQuery, $wordDelimRegExpr, '.*')"/>
+      </xsl:when>
+      <xsl:otherwise><xsl:value-of select="''"/></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <!-- Deletes the substring up to the query term -->
+  <xsl:variable name="substringBefore" select="replace($inputString, $queryRegExprSubstringAfter, '$1', 'i')"/>
+  <!-- Deletes the substring after the query term -->
+  <xsl:variable name="substringAfter" select="replace($inputString, $queryRegExprSubstringBefore, '$1', 'i')"/>
+  <xsl:choose>
+    <xsl:when test="matches($inputString, $queryRegExprSubstringBefore, 'i')">
+      <!-- Prints the original part of the substring up to the first occurrence of the query term -->
+      <xsl:value-of select="$substringBefore"/>
+      <!-- Highlight the query term -->
+      <xsl:variable name="matchQueryTermRegExpr">
+        <xsl:choose>
+          <xsl:when test="$mode = 'phrase'">
+            <xsl:value-of select="concat('^.*?', '(', $textQuery, ')', '.*')"/>
+          </xsl:when>
+          <xsl:when test="$mode = 'fakeWord'">
+            <xsl:value-of select="concat('^.*?', '(', $textQuery, ')', '.*')"/>
+          </xsl:when>
+          <xsl:when test="$mode = 'word'">
+            <xsl:value-of select="concat('^.*?', $wordDelimRegExpr, '(', $textQuery, ')', $wordDelimRegExpr, '.*')"/>
+          </xsl:when>
+          <xsl:otherwise><xsl:value-of select="''"/></xsl:otherwise>
+        </xsl:choose>
+      </xsl:variable>
+      <xsl:variable name="matchQueryTerm" select="replace($inputString, $matchQueryTermRegExpr, '$1', 'i')"/>
+      <span style="background-color: yellow;">
+        <xsl:value-of select="$matchQueryTerm"/>
+      </span>
+      <!-- Recursive call of this function with the substring after the first occurrence of the term: further occurrences of the query 
+      term  -->
+      <xsl:sequence select="text:highlight($substringAfter, $luceneQuery, $mode)"/>
+    </xsl:when>
+    <!-- if no occurrence of the query term could be found the whole string is printed -->
+    <xsl:otherwise>
+      <xsl:value-of select="$inputString"/>
+      </xsl:otherwise>
+  </xsl:choose>
+</xsl:function>
+
+<!--
+<xsl:function name="text:limitHighligthedString">
+  <xsl:param name="inputString" />
+  <xsl:param name="countChar" as="xs:integer"/>
+  <xsl:variable name="substringBeforeHighlight" select="substring-before($inputString, '&lt;span')"/>
+  <xsl:variable name="substringAfterHighlight" select="substring-after($inputString, '&lt;span&gt;>')"/>
+  <xsl:variable name="result">
+  ... <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)"/> ...
+  </xsl:variable>
+  <xsl:sequence select="$result"/>
+</xsl:function>
+-->
+
+<xsl:function name="text:limitHighligthedString">
+  <xsl:param name="inputSequence" as="node()*"/>
+  <xsl:param name="countChar" as="xs:integer"/>
+  <xsl:variable name="before" select="$inputSequence[1]"/>
+  <xsl:variable name="beforeLimited" select="substring($before, string-length($before) - $countChar)"/>  
+  <xsl:variable name="firstSpan" select="$inputSequence[2]"/>
+  <xsl:variable name="after" select="$inputSequence[position() > 2]"/>
+  <xsl:variable name="afterLimited" select="substring($after, 0, $countChar)"/>  
+  <xsl:variable name="result">
+  ... <xsl:sequence select="$before"/><xsl:sequence select="$firstSpan"/><xsl:sequence select="$after"/> ...
+  </xsl:variable>
+  <xsl:sequence select="$result"/>
+</xsl:function>
+
+<xsl:variable name="ftQueryName" select="/result/ft-query/name"/>
+<xsl:variable name="ftQueryStr" select="concat('&amp;', 'ft-query=', $ftQueryName)"/>
+<xsl:variable name="ftQueryMode">
+  <xsl:choose>
+  <xsl:when test="matches($ftQueryName, concat('&quot;', '.*', '&quot;'))">
+    <xsl:value-of select="'phrase'"/>
+  </xsl:when>
+  <xsl:when test="string-length($ftQueryName) = 0">
+    <xsl:value-of select="'false'"/>
+  </xsl:when>
+  <!-- Because there are  problems in recognizing words (in mode word) this fake mode is used (same as phrase mode)  -->
+  <xsl:otherwise><xsl:value-of select="'fakeWord'"/></xsl:otherwise>
+  </xsl:choose>
+</xsl:variable>
+<xsl:variable name="ftQueryValue">
+  <xsl:choose>
+  <xsl:when test="/result/ft-query[node()]"><xsl:value-of select="$ftQueryStr"/></xsl:when>
+  <xsl:otherwise><xsl:value-of select="''"/></xsl:otherwise>
+  </xsl:choose>
+</xsl:variable>
+
+<xsl:template match="result">
+  <html><body>
+    <xsl:variable name="ft-query-name" select="/result/ft-query/name"/>
+    <xsl:for-each select="document-description">
+      <h2>
+      <xsl:for-each select="info">
+        <xsl:value-of select="author"/>.
+        <xsl:value-of select="title"/>.
+        <xsl:value-of select="place"/>, 
+        <xsl:value-of select="date"/>
+      </xsl:for-each>
+      </h2>
+    </xsl:for-each>
+    <form action="" method="get"></form>
+    <xsl:for-each select="page">
+      <xsl:variable name="documentName" select="/result/document-description/document-name"/>
+      <xsl:variable name="countPages" select="/result/document-description/count-pages"/>
+      <xsl:variable name="number" select="number(number)"/>
+      <xsl:variable name="documentValue" select="concat('document=', $documentName)"/>
+      <xsl:variable name="pnValue" select="concat('pn=', $number)"/>
+      <xsl:variable name="modeImageValue" select="concat('mode=', 'image')"/>
+      <xsl:variable name="modeXmlValue" select="concat('mode=', 'xml')"/>
+      <xsl:variable name="modeTextValue" select="concat('mode=', 'text')"/>
+      <xsl:variable name="imageLink" select="concat($documentValue, '&amp;', $pnValue, '&amp;', $modeImageValue, $ftQueryValue)"/>
+      <xsl:variable name="textLink" select="concat($documentValue, '&amp;', $pnValue, '&amp;', $modeTextValue, $ftQueryValue)"/>
+      <xsl:variable name="xmlLink" select="concat($documentValue, '&amp;', $pnValue, '&amp;', $modeXmlValue, $ftQueryValue)"/>
+      <table width="100%">
+        <colgroup>
+          <col width="30%"/>
+          <col width="70%"/>
+        </colgroup>
+        <tr>
+        <td align="left" nowrap="true">
+          [<a href="?{$textLink}">Text</a>] 
+          [<a href="?{$imageLink}">Image</a>]
+          [XML] 
+        </td>
+        <td align="right" nowrap="true">
+          <td>
+            <xsl:choose>
+              <xsl:when test="$number &gt; 1">
+                <a href="?{$documentValue}&amp;pn={$number - 1}&amp;{$modeXmlValue}{$ftQueryValue}"><img src="images/left.gif" alt="page-down" border="0"/></a>
+              </xsl:when>
+              <xsl:otherwise>
+                <a href="?{$xmlLink}"><img src="images/left.gif" alt="page-down" border="0"/></a>
+              </xsl:otherwise>
+            </xsl:choose>
+          </td>
+          <td nowrap="true">
+            <xsl:value-of select="$number"/> / <xsl:value-of select="$countPages"/> 
+          </td>
+          <td>
+            <xsl:choose>
+              <xsl:when test="$number &lt; $countPages">
+                <a href="?{$documentValue}&amp;pn={$number + 1}&amp;{$modeXmlValue}{$ftQueryValue}"><img src="images/right.gif" alt="page-up" border="0"/></a>
+              </xsl:when>
+              <xsl:otherwise>
+                <a href="?{$xmlLink}"><img src="images/right.gif" alt="page-down" border="0"/></a>
+              </xsl:otherwise>
+            </xsl:choose>
+          </td>
+          <td nowrap="true">
+            <input type="hidden" name="document" value="{$documentName}"/>
+            Page: <input type="text" size="3" name="pn" value="{$number}"/> 
+            <input type="hidden" name="mode" value="xml"/>
+            <xsl:if test="/result/ft-query[node()]">
+              <input type="hidden" name="ft-query" value="{$ftQueryName}"/>
+            </xsl:if>
+          </td>
+        </td>
+        </tr>
+      </table>
+      <hr/>   
+      <table align="middle" width="100%">
+        <colgroup>
+          <col width="70%"/>
+          <col width="30%"/>
+        </colgroup>
+        <tr>
+          <td align="left" valign="top">
+            <xsl:for-each select="content">
+              <xsl:apply-templates/>
+            </xsl:for-each>
+          </td>
+          <xsl:if test="$ftQueryValue!=''">
+          <td align="left" valign="top">
+            <b><xsl:value-of select="/result/ft-query/result/size"/> Hits: "<xsl:value-of select="$ftQueryName"/>"</b>
+            <ol>
+              <xsl:for-each select="/result/ft-query/result/hits/hit">
+              <li>
+                <xsl:variable name="hitPN" select="pn"/>
+                <xsl:variable name="hitPosOfS" select="pos-of-s"/>
+                <a href="?{$documentValue}&amp;pn={$hitPN}&amp;{$modeXmlValue}{$ftQueryValue}">Page <xsl:value-of select="$hitPN"/>, Sentence <xsl:value-of select="$hitPosOfS"/></a>:<br></br>
+                <!-- Highlight the query terms in each hit  -->
+                <xsl:variable name="highlightedSentenceSeq" select="text:highlight(s, $ftQueryName, $ftQueryMode)"/>
+                <xsl:sequence select="text:limitHighligthedString($highlightedSentenceSeq, 100)"/>
+              </li>
+              </xsl:for-each>
+            </ol>
+          </td>
+          </xsl:if>
+        </tr>
+      </table>
+      <hr/>
+      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
+      <br/>
+      [<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>]
+    </xsl:for-each>
+  </body></html>
+</xsl:template>
+
+
+<xsl:template match="attribute()|element()|text()|comment()|processing-instruction()">
+  <xsl:copy>
+    <xsl:apply-templates select="attribute()|element()|text()|comment()|processing-instruction()"/>
+  </xsl:copy>
+</xsl:template>
+
+<xsl:template match="element()|text()|comment()|processing-instruction()">
+  <xsl:variable name="elementName" select="name()"/>
+  <span style="color: brown;">&lt;<xsl:value-of select="$elementName"/><xsl:apply-templates select="attribute()"/>&gt;</span>
+    <xsl:apply-templates select="element()|text()|comment()|processing-instruction()"/>
+  <span style="color: brown;">&lt;/<xsl:value-of select="$elementName"/>&gt;</span>
+  <br/>
+</xsl:template>
+
+<xsl:template match="attribute()">
+  <xsl:variable name="attributeName" select="name()"/>
+  <xsl:text> </xsl:text><xsl:value-of select="$attributeName"/>=<xsl:value-of select="."/>
+    <xsl:apply-templates select="attribute()"/>
+</xsl:template>
+
+<!-- If ft-query is set then highlight all term occurrences for the fulltext query else show the text -->
+<xsl:template match="text()">
+  <xsl:choose>
+  <xsl:when test="$ftQueryMode != 'false'">
+    <xsl:sequence select="text:highlight(., $ftQueryName, $ftQueryMode)"/>
+  </xsl:when>
+  <xsl:otherwise>
+    <xsl:value-of select="."/>
+  </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+</xsl:stylesheet>