6.キーワードの自動リンク
文中で<keyword>で囲った語句をキーワードとして、他の場所で同じ語句が現れた時に自動的にリンクします。
<?xml-stylesheet type="text/xsl" href="sample.xsl"?> <html> <head> <title>5.キーワード自動リンク</title> </head> <body> <h1>5.キーワード自動リンク</h1> <p> <keyword>で囲まれた語句をキーワードとして登録し、 文中で自動的にリンクします。 </p> <h2><keyword>りんご</keyword></h2> りんごは赤い。<br/> <h2><keyword>みかん</keyword></h2> みかんは黄色い。りんごと比べると、皮をむくのが簡単。 </body> </html>

「りんご」や「みかん」が自動的にリンクされています。
<?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" version="1.0"> <!-- 出力モード --> <xsl:output method="html" encoding="Shift_JIS"/> <!-- 処理命令は無視 --> <xsl:template match="processing-instruction()"/> <!-- ノードや属性はそのまま出力 --> <xsl:template match="@*|node()" priority="-1.0"> <xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy> </xsl:template> <!-- キーワード自動リンク --> <xsl:template match="keyword"> <a name="{count(preceding::keyword)+1}"/> <xsl:apply-templates mode="nolink"/> </xsl:template> <xsl:template match="text()" name="text"> <xsl:param name="str" select="."/> <xsl:variable name="node"select="/descendant::keyword[string(.)!=''][contains($str, .)][1]"/> <xsl:choose> <xsl:when test="$node"> <xsl:call-template name="text"> <xsl:with-param name="str"
select="substring-before($str, string($node))"/> </xsl:call-template> <a href="#{count($node/preceding::keyword[string(.)!=''])+1}"> <xsl:value-of select="string($node)"/></a> <xsl:call-template name="text"> <xsl:with-param name="str"
select="substring-after($str, string($node))"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:value-of select="$str"/> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template match="text()" mode="nolink"> <xsl:copy/> </xsl:template> </xsl:stylesheet>
keywordに対応するテンプレート<xsl:template match="keyword">では、リンク先となるアンカーを出力しています。その後、<xsl:apply-templates/>で<keyword>の中身の処理に移っています。
<xsl:template match="keyword"> <a name="{count(preceding::keyword)+1}"/> <xsl:apply-templates mode="nolink"/> </xsl:template>
また、文中のテキストに対応するテンプレート<xsl:template match="text()" name="text">では、キーワードが含まれているかを確認し、含まれていればリンクを出力するようになっています。
<xsl:choose> <xsl:when test="$keyword!='' and contains($str, $keyword)"> ...(キーワードが含まれている時の処理) </xsl:when> <xsl:otherwise> ...(キーワードが含まれていない時の処理) </xsl:otherwise> </xsl:choose>
さらに、<xsl:when>の中では自分自身を呼び出して再帰処理を行っています。
応用例1
外部のXML文章のキーワードに対してリンクします。
... <xsl:otherwise> <xsl:variable name="node2" select="$root//keyword[document(@src)//keyword[string(.)!=''and contains($str, .)]][1]"/> <xsl:choose> <xsl:when test="$node2 and $src=''"> <xsl:call-template name="text"> <xsl:with-param name="str" select="$str"/> <xsl:with-param name="root" select="document($node2/@src)"/> <xsl:with-param name="src" select="$node2/@src"/> </xsl:call-template> </xsl:when> <xsl:when test="$node2"> <xsl:call-template name="text"> <xsl:with-param name="str" select="$str"/> <xsl:with-param name="root" select="document($node2/@src)"/> <xsl:with-param name="src" select="concat($src, '/', $node2/@src)"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:value-of select="$str"/> </xsl:otherwise> </xsl:choose> </xsl:otherwise> ...
最初のスクリプトの一部に、外部のキーワードを読み込むためのスクリプトが追加されています。
