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
<?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を追加して実行することで、リンク先を簡単に切り替えることができます。
<msxsl:script>を用いて、JScriptで独自の関数を作成することができます。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>
<?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 外部スクリプトから使用するタイプ
リンク先の切り替えを、他のスクリプトからも使用できるように調整したものです。
<?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スクリプトから呼び出して使用しています。


