SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

特集記事

ホームページ製作を楽にする7つのXSLTスクリプト

XSLTでXHTMLを操作しホームページ作成作業を半自動化する

6.キーワードの自動リンク

 文中で<keyword>で囲った語句をキーワードとして、他の場所で同じ語句が現れた時に自動的にリンクします。

変換元ファイル
<?xml-stylesheet type="text/xsl" href="sample.xsl"?>

<html>
<head>
  <title>5.キーワード自動リンク</title>
</head>
<body>
<h1>5.キーワード自動リンク</h1>

<p>
  &lt;keyword&gt;で囲まれた語句をキーワードとして登録し、
文中で自動的にリンクします。
</p>

<h2><keyword>りんご</keyword></h2>
りんごは赤い。<br/>

<h2><keyword>みかん</keyword></h2>
みかんは黄色い。りんごと比べると、皮をむくのが簡単。

</body>
</html>
変換結果
変換結果

 「りんご」や「みかん」が自動的にリンクされています。

XSLTスクリプト
<?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文章のキーワードに対してリンクします。

XSLTスクリプト一部抜粋
...
<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>
...

 最初のスクリプトの一部に、外部のキーワードを読み込むためのスクリプトが追加されています。

次のページ
7.サムネイルの自動生成

この記事は参考になりましたか?

特集記事連載記事一覧

もっと読む

この記事の著者

ひだちのいろ(ヒダチノイロ)

大学生。IT関係の仕事につくのが夢です。かやねずみの巣

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/1055 2008/08/26 13:37

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー