SHOEISHA iD

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

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

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

特集記事

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

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

3.ローカルテスト時とアップロード時でのリンク先の切り替え

 XSLT変換を利用してホームページの製作をする場合、製作中は変換元のXMLファイルを扱いますが、アップロードするときはそれをHTMLに書き出してIE以外のブラウザでも観覧可能な形にします。この場合、ローカルテスト時の時には「index.xml」を、アップロード時には「index.html」をリンク先に指定したくなることがよくあります。次のXSLTスクリプトは、msxslコマンドを実行する時にパラメータに値を設定することで、リンク先の拡張子を「.xml」から「.html」に変更します。

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

<html>
<head>
  <title>3.ローカルテスト時とアップロード時でのリンク先の切り替え
  </title>
</head>
<body>
<h1>3.ローカルテスト時とアップロード時でのリンク先の切り替え</h1>
XMLファイルを直接ブラウザで観覧する時と、
xsltコマンドを使用してHTMLファイルに保存した時とで、リンク先の拡張子を
「.xml」から「.html」に切り替えます。

xsltコマンドを使用するときは、次のようにパラメータを指定してください。

<p style="background-color:#eeeeee; padding:5px;">
<cdoe>
  xslt 「変換対象.xml」 「変換に使うXSLTスクリプト.xsl」 -o
 「出力.html」 <span style="font-weight:bold;">transmode=yes</span>
</cdoe>
</p>

<p>
  <a href="app1.xml">応用編1へ</a>
</p>

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

 変換元ファイルを直接開くと、リンク先は「app1.xml」になります。msxslを使用して変換を行う時に、transmode=yesという記述を追加すると、リンク先は「app1.html」になります。

xslt 「変換対象.xml」 「変換に使うXSLTスクリプト.xsl」 -o 「出力.html」
 transmode=yes
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:param name="transmode" select="no"/>

  <msxsl:script language="JScript" implements-prefix="xmlns">
    <![CDATA[
      function replace(str, from, to) { return str.replace(from, to); }
      ]]>
  </msxsl:script>

  <xsl:template match="a/@href">
    <xsl:choose>
      <xsl:when test="$transmode='yes'">
        <xsl:attribute name="href"><xsl:value-of
          select="xmlns:replace(string(.), '.xml', '.html')"/>
        </xsl:attribute>
      </xsl:when>
      <xsl:otherwise>
        <xsl:copy/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

</xsl:stylesheet>

 <xsl:param name="transmode" select="no"/>は、「transmode」というパラメータのデフォルト値が「no」であることを示します。MSXSLで変換を行う時に、transmode=yesという記述を追加することで、transmodeパラメータの値を「yes」に変更することができます。

 その後の<msxsl:script language="JScript" implements-prefix="xmlns">は、変換に使用する独自の関数をJScriptで記述しています。この変換では、hrefの中身の拡張子を変更するのに、「.xml」を「.html」に置き換えるという処理が必要になりますが、XSLT変換にもともと利用できる関数の中に文字列を置き換える関数がありません。そこで、このように独自の関数を作成して、変換に使用しています。

 最後の<xsl:template match="a/@href">には、<a>の属性hrefに対応する処理が書かれています。transmodeの値がnoの時は、<xsl:copy/>によって変換元のhref属性の内容がそのまま出力されます。transmodeの値がyesの時は、先ほど作った関数で、href属性の「.xml」を「.html」に置き換えて出力しています。

 アップロード用のHTMLを出力する時だけ、MSXSLにtransmode=yesを追加して実行することで、リンク先を簡単に切り替えることができます。

JScriptで独自に関数を定義する
 XSLTには、文字列や数値やノードを処理する関数があらかじめ定義されていて、必要に応じて使用することができます。また、それらの関数の能力を超えて処理を行いたい場合は、MSXSLの独自拡張である<msxsl:script>を用いて、JScriptで独自の関数を作成することができます。
 
translate関数で文字列は置き換えられない
 「2.タイトルにサイト名を自動的に追加」の「応用例1」で使用したtranslate関数はあらかじめXSLTで用意された文字列処理関数です。句読点を置き換えるのに使用しました。では、文字列の置き換えに、translateは使用できないのでしょうか? 実は、translateは、文字を置き換える関数なので、文字列の置き換えには使用できないのです。
 

応用例1 hrefの内容をhref2の内容に切り替える

 拡張子だけではなく、hrefの内容全体をhref2に切り替えます。ローカルとサーバーでのディレクトリ構造が異なる時や複数のサーバーにファイルをアップロードする際に役立ちます。

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

<html>
<head>
  <title>3.応用例1 hrefの内容をhref2の内容を切り替える</title>
</head>
<body>
<h1>3.応用例1 hrefの内容をhref2の内容を切り替える</h1>

<p>
より汎用性のある、リンク先切り替えです。
通常は、hrefで指定した「sample.xml」にリンクされていますが、変換時にtransmode
パラメータにyesが指定されると、
href2の内容である「0.何もしないXSLTスクリプト」に切り替わります。
</p>

<p>
  <a href="sample.xml" href2="../0/sample.xml">リンク</a>
</p>

</body>
</html>
変換結果
変換結果
XSLTスクリプト
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                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:param name="transmode" select="no"/>
  <xsl:template match="a/@href">
    <xsl:choose>
      <xsl:when test="$transmode='yes'">
        <xsl:attribute name="href"><xsl:value-of select="../@href2"/>
        </xsl:attribute>
      </xsl:when>
      <xsl:otherwise>
        <xsl:copy/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <xsl:template match="a/@href2"/>

</xsl:stylesheet>

 「transmode」が「yes」の時の動作が、href2を参照するものに変更されています。

応用例2 外部スクリプトから使用するタイプ

 リンク先の切り替えを、他のスクリプトからも使用できるように調整したものです。

app2.xsl
<?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:param name="transmode" select="no"/>
  <msxsl:script language="JScript" implements-prefix="xmlns">
    function replace(str, from, to) { return str.replace(from, to); }
  </msxsl:script>

  <xsl:template match="a/@href" name="switchHrf">
    <xsl:variable name="href" select="string(.)"/>
    <xsl:choose>
      <xsl:when test="$transmode='yes'">
        <xsl:attribute name="href">
          <xsl:value-of select="xmlns:replace($href, '.xml', '.html')"/>
        </xsl:attribute>
      </xsl:when>
      <xsl:otherwise>
        <xsl:attribute name="href"><xsl:value-of select="$href"/>
        </xsl:attribute>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

</xsl:stylesheet>

 不必要なテンプレートを削り、<xsl:template match="a/@href" name="switchHref">name属性を加えています。この「app2.xsl」は以降のXSLTスクリプトから呼び出して使用しています。

次のページ
4.ヘッダとフッタの自動追加

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

特集記事連載記事一覧

もっと読む

この記事の著者

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

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

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

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

この記事をシェア

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

イベント

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

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

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

メールバックナンバー