Thomas J.S.: Mit XML + XSL Glossarbegriffe Erkennen und Verlinken

Beitrag lesen

Hallo,

ich habe eine XML Datei mit viel Text und ein Glossar. Zu jedem Glossarbegriff habe ich ein Schlagwort/Suchwort

Wollte nun Fragen ob es mit Hilfe von XSLT irgendwie möglich ist das ich den Inhalt von den Elementen nach den Schlagworten durchsuche und sobald er eines im Text findet, einen Link zu dem Text vom Glossar einfügt.
Von dem Aufbau der XML Datei soll sich ansonsten nichts ändern

Grober Aufbau der XML Datei:
<root>
<kapitel>
<seite>
<zeile ein="true"> Hier steht ganz viel Inhalt. Sobald ein Begriff hier auftaucht der im Glossar näher erklärt ist, soll dieser zu einem Link werden der an die richtige Stelle im Glossar verweist</zeile>
<marku>Auch andere Elemente kommen im Seiten Element vor</marku>
</seite>
<seite>....</seite><seite>....</seite><seite>....</seite>
</kapitel>
</root>

Das könnte so gehen:

<xsl:template match="seite//text()">
   <xsl:call-template name="makelink">
 <xsl:with-param name="text" select="normalize-space(.)" />
   </xsl:call-template>
</xsl:template>

<xsl:template name="makelink">
 <xsl:param name="text" />
 <xsl:variable name="wort" select="substring-before($text, ' ')" />
 <xsl:if test="$wort != ''">
  xsl:choose
   <xsl:when test="$wort = /root/glossar/eintrag/titel">
    <a href="#{generate-id(/root/glossar/eintrag[titel = $wort])}"><xsl:value-of select="$wort" /></a>xsl:text </xsl:text>
   </xsl:when>
   xsl:otherwise
    <xsl:value-of select="concat($wort, ' ')" />
   </xsl:otherwise>
  </xsl:choose>
  <xsl:call-template name="makelink">
   <xsl:with-param name="text" select="normalize-space(substring-after($text, $wort))" />
  </xsl:call-template>
 </xsl:if>
</xsl:template>

Damit du sieht was da passiert hier ein koplettest Bsp:

--------- xml ---------------
<?xml version="1.0" encoding="iso-8859-1"?>
<root>
<kapitel>
<seite>
<zeile ein="true">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nullam tincidunt. Nulla sit amet urna in est gravida interdum. Aenean suscipit. Vestibulum
non augue.<foo>Vivamus luctus enim ac nunc adipiscing dictum. Nunc ac lorem eget dolor aliquam laoreet. Suspendisse potenti.</foo> Fusce urna. Nunc
congue, neque eu pharetra commodo, turpis dolor molestie erat, a adipiscing ipsum lacus a nisl. Quisque eget elit. Morbi odio. Duis sit amet pede.
Vivamus sed enim in erat vehicula fringilla. Duis viverra. Nam condimentum, mi vel mollis vulputate, libero orci sodales urna, a tempor odio lectus
eget wisi. <bar>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Aliquam vestibulum tortor nec turpis.</bar>
Aenean suscipit adipiscing sem. Vivamus id felis. Praesent ornare malesuada tortor.
</zeile>
</seite>
<seite>
Cras ultricies. Vivamus elementum, sapien quis rhoncus feugiat, nibh est posuere purus, a fringilla ante nibh at turpis. Fusce ante tortor, consequat
eu, sollicitudin quis, <foo>bibendum at, sem. Cras venenatis mollis risus. <bar>Quisque condimentum gravida arcu. Donec rutrum mauris in sapien.</bar>
Pellentesque aliquam suscipit felis. Cras velit. Cras malesuada ligula et tellus. Ut lacus. Donec feugiat. Vivamus justo. Curabitur feugiat.</foo> Nullam
lorem odio, venenatis non, ultrices a, facilisis sit amet, metus. Maecenas elit.
</seite>
</kapitel>
<glossar>
 <eintrag>
  <titel>Vivamus</titel>
  <text>bla bla bla bla</text>
 </eintrag>
 <eintrag>
  <titel>Vestibulum</titel>
  <text>bla bla bla</text>
 </eintrag>
 <eintrag>
  <titel>condimentum</titel>
  <text>bla bla bla</text>
 </eintrag>
</glossar>
</root>

------------------- xsl ---------------------
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
 <html>
  <head>
   <title>Untitled</title>
  </head>
  <body>
   <xsl:apply-templates />
  </body>
 </html>
</xsl:template>

<xsl:template match="kapitel/seite">
 <p>
  <xsl:apply-templates />
 </p>
</xsl:template>

<xsl:template match="seite//*">
 <span style="color:red">[<xsl:value-of select="name()" />]</span>
  <xsl:apply-templates />
 <span style="color:red">[/<xsl:value-of select="name()" />]</span>
</xsl:template>

<xsl:template match="seite//text()">
 <strong>{</strong><xsl:call-template name="makelink">
  <xsl:with-param name="text" select="normalize-space(.)" />
 </xsl:call-template><strong>}</strong>
</xsl:template>

<xsl:template match="glossar">
 <dl>
  <xsl:for-each select="eintrag">
   <dd id="{generate-id(.)}">
    <xsl:value-of select="titel" />
   </dd>
   <dt>
    <xsl:value-of select="text" />
   </dt>
  </xsl:for-each>
 </dl>
</xsl:template>

<xsl:template name="makelink">
 <xsl:param name="text" />
 <xsl:variable name="wort" select="substring-before($text, ' ')" />
 <xsl:if test="$wort != ''">
  xsl:choose
   <xsl:when test="$wort = /root/glossar/eintrag/titel">
    <a href="#{generate-id(/root/glossar/eintrag[titel = $wort])}"><xsl:value-of select="$wort" /></a>xsl:text </xsl:text>
   </xsl:when>
   xsl:otherwise
    <xsl:value-of select="concat($wort, ' ')" />
   </xsl:otherwise>
  </xsl:choose>
  <xsl:call-template name="makelink">
   <xsl:with-param name="text" select="normalize-space(substring-after($text, $wort))" />
  </xsl:call-template>
 </xsl:if>
</xsl:template>
</xsl:stylesheet>

Grüße
Thomas