特定の条件で属性をつける
はじめに
ある特定の条件の場合だけ要素に属性をつけたいとする.例として
xsltの中のcolor変数に値がある場合はbody要素のcolor属性に変数の値をつける
と言う場合を考えてみよう.xsltプロセッサはSaxonを使用する.下記の例の中にある${saxon_home}
はSaxonをインストールしたディレクトリのことだ.colorにblueを設定して
$ java -cp "${saxon_home}/saxon8.jar;." net.sf.saxon.Transform -novw foo.xml foo.xsl color=blue
とした場合には
<?xml version="1.0" encoding="UTF-8"?>
<body color="blue"> <!-- color属性に引数で指定したblueを設定 -->
ここに本文
</body>
colorに何も値を設定せずに
$ java -cp "${saxon_home}/saxon8.jar;." net.sf.saxon.Transform -novw foo.xml foo.xsl
とした場合には
<?xml version="1.0" encoding="UTF-8"?>
<body>
ここに本文
</body>
となるようにしたい.xmlはこんな内容にしておこう.
<!-- foo.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<root>
<foo/>
</root>
単純にbody要素を書き分けると整形式ではなくなる
xsltを考えよう.まず思いついたのはこんなものだが,これは整形式のxmlではないのでエラーとなり動かない.<xsl:choose>
で場合分けしている<body>
の閉じタグの位置がずれているためだ.
<!-- foo.xsl -->
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="color"/>
<xsl:template match="/root">
<xsl:choose>
<xsl:when test="$color">
<body color="{$color}"> <!-- bodyの閉じタグが同じレベルにないのでエラー -->
</xsl:when>
<xsl:otherwise>
<body> <!-- bodyの閉じタグが同じレベルにないのでエラー -->
</xsl:otherwise>
</xsl:choose>
ここに本文
</body>
</xsl:template>
</xsl:stylesheet>
body要素と本文を二重に書く
<body>
要素と本文を二重に書くとエラーはでなくなる.しかし,これは面倒だ.
<!-- foo.xsl -->
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="color"/>
<xsl:template match="/root">
<xsl:choose>
<xsl:when test="$color">
<body color="{$color}"> <!-- color属性がある場合 -->
ここに本文
</body>
</xsl:when>
<xsl:otherwise>
<body> <!-- color属性がない場合 -->
ここに本文
</body>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
文字列として扱ってみる
<body>
を文字列として組み立てるやり方もある.あまり格好は良くない.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="color"/>
<xsl:template match="/root">
<xsl:text disable-output-escaping="yes"><body</xsl:text>
<xsl:if test="$color">
<xsl:value-of select="concat(' color="',$color,'"')"/>
</xsl:if>
<xsl:text disable-output-escaping="yes">></xsl:text>
ここに本文
<xsl:text disable-output-escaping="yes"></body></xsl:text>
</xsl:template>
</xsl:stylesheet>
<xsl:attribute>
を使う
<xsl:attribute>
を使うともうちょっとスマートにできた.
<!-- foo.xsl -->
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="color"/>
<xsl:template match="/root">
<body>
<xsl:if test="$color">
<xsl:attribute name="color">
<xsl:value-of select="$color"/>
</xsl:attribute>
</xsl:if>
ここに本文
</body>
</xsl:template>
</xsl:stylesheet>