CLOVER🍀

That was when it all began.

XSLTを勉強する

ひょんなことから、仕事でXSLTを使うことになりました。この技術は学生の頃にちょろっと使ったことがあったのですが、あまり理解せず。そして、このXMLが嫌われている中で、これをお目にすることになるとは…。

まあ、いいです。やるだけやっておきましょう。

まずは、環境準備。今回、XSLTの変換処理にはJAXPを利用します。こちら、用意したソースです。

import javax.xml.transform.TransformerFactory
import javax.xml.transform.stream.{StreamResult, StreamSource}

object XsltExample {
  def main(args: Array[String]): Unit = {
    val (sourceXml, styleSheet) = args.length match {
      case 2 => (new StreamSource(args(0)), new StreamSource(args(1)))
      case _ =>
	println("""|Required 2 Arguments
		|  one: input XML source
		|  two: input XSL style-sheet
		|""".stripMargin)
	sys.exit(1)
    }

    val transformerFactory = TransformerFactory.newInstance
    val transformer = transformerFactory.newTransformer(styleSheet)
    val transformedXml = new StreamResult(System.out)

    transformer.transform(sourceXml, transformedXml)
  }
}

別に、Scalaである必要はないのですが…いいじゃないですか。

続いて、変換元となるXML

<?xml version="1.0" encoding="UTF-8"?>
<persons>
  <person id="1">
    <firstName>Taro</firstName>
    <lastName>Suzuki</lastName>
  </person>
  <person id="2">
    <firstName>Hanako</firstName>
    <lastName>Tanaka</lastName>
  </person>
</persons>

こんな感じのXMLですが、今回はこれをid、firstName、lastNameと並ぶXHTMLのtableに変換してみたいと思います。

用意したXSLスタイルシート

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
		xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
		xmlns="http://www.w3.org/1999/xhtml">
  <xsl:output
      method="xml"
      indent="yes"
      encoding="UTF-8"
      doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"
      doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" />

  <xsl:template match="/">
    <html lang="ja">
      <head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
      </head>
      <title>Person to Table</title>
      <body>
	<table>
	  <tr><th>ID</th><th>First Name</th><th>Last Name</th></tr>
	  <xsl:apply-templates select="persons" />
	</table>
      </body>
    </html>
  </xsl:template>

  <xsl:template match="persons">
    <xsl:for-each select="person">
      <tr>
	<td><xsl:value-of select="@id" /></td>
	<td><xsl:value-of select="firstName" /></td>
	<td><xsl:value-of select="lastName" /></td>
      </tr>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

これを実行すると…

> run persons.xml persons-to-table.xsl
[info] Running XsltExample persons.xml persons-to-table.xsl
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="ja" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<title>Person to Table</title>
<body>
<table>
<tr>
<th>ID</th>
<th>First Name</th>
<th>Last Name</th>
</tr>
<tr>
<td>1</td>
<td>Taro</td>
<td>Suzuki</td>
</tr>
<tr>
<td>2</td>
<td>Hanako</td>
<td>Tanaka</td>
</tr>
</table>
</body>
</html>

うん、一応うまくいってそうですね。