XSLT2.0基礎文法最速(?)マスター [XSLT]

| コメント(0) | トラックバック(0)

なんか***基礎文法マスターなるものが流行っているそうなのでやってみる。

2010-02-02 19時追記>

1. 基礎の基礎

XSLTとは、XML文書をXML文書もしくはプレーンテキストに変換するためのルールをXMLで記述する変換用言語です。

2007年に勧告が出されたXSLT version 2.0 はXSLT version 1.0 と比べて、複数の入出力文書の取り扱い、変数の型指定、sequenceのサポート、ユーザ関数定義などが追加されています。

プログラミング言語としてみた場合は、関数型言語属だと思います

詳細な仕様は以下のリンクから

XSLTプロセッサはとりあえず Saxon 使っときゃいいんじゃないかな

2. 基本文法

基本的にはXSLTで変換の流れを記述し、XSLTの各要素の属性値として記述されるXPath式で変換対象の取得や加工を行います

<?xml version="1.0" encoding="utf-8"?>
<!-- root要素の名前空間宣言はこのままコピペするといいです -->
<xsl:stylesheet version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:fn="http://www.w3.org/2005/xpath-functions"
  exclude-result-prefixes="xsl xs fn"
  >
  <!-- 出力文書のフォーマットを指定します。 xml, html, xhtml, text のどれかです -->
  <xsl:output method="xml" />

  <xsl:template match="/"> <!-- 入力文書のルートにマッチし、変換を行います -->
    <!-- ルート要素がtestで、入力文書のtextを内容として持つXML文書を作成します -->
    <test><xsl:value-of select="." /></test>
  </xsl:template>

</xsl:stylesheet>

3. 実行

各XSLTプロセッサのドキュメントを参照してください。(ぇー

参考までに、Saxon 9.x on Java の場合は


c:\> java -jar saxon9.jar -xsl:スタイルシート.xsl -s:変換元XMLドキュメント.xml [-o:出力ファイル名]

4. コメント

XMLコメント <!-- --> を使います。

5. メッセージ出力

xsl:message 要素で出力文書とは別にメッセージを出力できます。メッセージが出力される場所はXSLTプロセッサ依存です。

<!-- 変数 i の内容をメッセージ出力 -->
<xsl:message select="$i" />
<!-- terminate属性を指定すると、メッセージ出力後に変換処理を停止します -->
<xsl:message terminate="yes">何かエラー!</xsl:message>

6. 変数

変数は xsl:variable 要素で宣言・定義します。 変数の有効範囲は親要素で囲まれた範囲です。宣言・定義は同時に行わなければならず、後で内容を変更することはできません

name属性で変数名を、as属性で型を指定します。変数の内容はselect属性に書かれたxpath式か、要素内容です。

変数やリテラルの演算や関数適用はXPath式内で行います。

<!-- i という名前の xs:integer型の変数を宣言・定義する -->
<xsl:variable name="i" as="xs:integer" select="1" />
<!-- XML断片を変数に持つこともできます -->
<xsl:variable name="elem" as="element()">
<root><parent><child>YO HO!</child></parent></root>
</xsl:variable> 

7. 数値型

xs:integerxs:double など様々な数値型が 用意されています

四則演算+α

<xsl:value-of select="$i + 1" /> <!-- 加算 -->
<xsl:value-of select="$i - 1" /><!-- 減算 -->
<xsl:value-of select="$i * 2" /><!-- 乗算 -->
<xsl:value-of select="$i div 2" /><!-- 除算 -->
<xsl:value-of select="$i idiv 2" /><!-- 除算(商) -->
<xsl:value-of select="$i mod 2" /><!-- 除算(余り) -->

8. 文字列型

xs:string型です。

<!-- xpath式中のリテラルはシングルクオートかダブルクオートで囲みます -->
<xsl:value-of select="'abcde'" />
<xsl:variable name="str" as="xs:string">要素内容ならそのまま書けます</xsl:variable>

文字列操作

<!-- 結合 -->
<xsl:value-of select="fn:concat('a', 'b', 'c')" /> <!-- abc -->
<xsl:value-of select="fn:string-join('a', 'b', 'c', ',')" /> <!-- a,b,c -->

<!-- 分割 -->
<xsl:value-of select="fn:tokenize('a,b, c', ',\s*')" /> <!-- ('a', 'b', 'c') -->

<!-- 長さ -->
<xsl:value-of select="fn:string-length('abcde')" /> <!-- 5 -->

<!-- 部分文字列 -->
<xsl:value-of select="fn:substring('abcde', 3)" /> <!-- cde -->
<xsl:value-of select="fn:substring('abcde', 3, 2)" /> <!-- cd -->

<!-- 検査 -->
<xsl:value-of select="fn:contains('abcde', 'bcd')" /> <!-- true -->
<xsl:value-of select="fn:starts-with('abcde', 'abc')" /> <!-- true -->
<xsl:value-of select="fn:matches('abcde', '\d+')" /> <!-- false --> 

9. sequece型

任意の型に対する sequece を作成できます。型名の後ろに ?(要素数は0か1), *(要素数は0以上), +(要素数は1以上) のいずれかをつけます。要素数が合わない場合はエラーです。また、参照する際のインデクスは1から始まります

<!-- sequence型  -->
<xsl:variable name="sa" as="xs:string*" select="('a', 'b', 'c')" />
<!-- xsl:sequece を使って作成することも出来る -->
<xsl:variable name="ia" as="xs:integer+">
  <xsl:sequence select="1" />
  <xsl:sequence select="0" />
  <xsl:sequence select="9" />
</xsl:variable>
<!-- to演算子を使って整数のsequenceを生成できる -->
<xsl:variable name="ia2" as="xs:integer*" select="1 to 3" /> <!-- (1, 2, 3) -->

sequece 操作

<!-- 先頭を取り出す -->
<xsl:value-of select="$sa[1]" />
<!-- 結合 -->
<xsl:value-of select="(1,2,3), (4,(5,6))" /> <!-- (1,2,3,4,5,6) -->
<!-- 走査 -->
<xsl:value-of select="fn:index-of($sa, 'b')" /> <!-- 2 -->
<!-- 検査 -->
<xsl:value-of select="fn:existst($sa)" /> <!-- true -->
<xsl:value-of select="fn:empty($sa)" /> <!-- false -->
<!-- 削除 -->
<xsl:value-of select="fn:remove($sa, 2)" /> <!-- ('a', 'c') -->
<!-- 反転 -->
<xsl:value-of select="fn:reverse($sa)" /> <!-- ('c', 'b', 'a') -->
<!-- 部分sequence -->
<xsl:value-of select="fn:subsequence($sa, 2, 2)" /> <!-- ('b', 'c') -->

10. 辞書型

ありません どうしても欲しい場合は、element()型変数で代用します。

<xsl:variable name="dict" as="element()">
<dict>
<key1>VALUE1</key1>
<key2>VALUE2</key2>
</dict>
</xsl:variable>
<xsl:value-of select="$dict//key1" /> <!-- VALUE1 -->

11. 制御構造

xsl:template

match属性内のXPath式にマッチするXMLノードを変換するルールを子要素に記述します。

xsl:param要素を記述して受け取るパラメタを宣言することもできます。

<!-- foo要素(ルート要素)の子要素である2番目のbar用の子要素であるfobar属性が'hoge'であるbaz要素 を変換する -->
<xsl:template match="/foo/bar[2]/baz[@fobar='hoge']">
  <xsl:text>変換結果</xsl:text>
</xsl:template>

xsl:apply-templates

select属性内のXPath式の内容にマッチするxsl:templateを適用します。子要素にxsl:with-paramを記述することでパラメタを渡すことも出来ます

<xsl:apply-templates select="/foo">
  <xsl:with-param name="param1" as="xs:integer" select="1" />
  <xsl:with-param name="param2" as="xs:string">パラメータ</xsl:with-param>
</xsl:apply-templates>

xsl:if

test属性内のXPath式が真と見なされる場合、要素内容を評価します。他の言語でのelseに相当するものを使いたい場合は後述のxsl:chooseを使います

<xsl:if test="$i = 1">
  <xsl:text>$i は 1 です。</xsl:text>
</xsl:if>

xsl:when

子要素として1個以上のxsl:when要素と 0個か1個のxsl:otherwiseを記述します。 test属性内のXPath式が真と見なされる最初のxsl:when要素の内容が評価されます。 どのwhenにも引っかからなかった場合、otherwiseがあればotherwiseの内容が評価されます。

<xsl:choose>
  <xsl:when test="$i = 1">
    <xsl:text>$i は 1 です</xsl:text>
  </xsl:when>
  <xsl:when test="$i gt 1">
    <xsl:text>$i は 1 より大きいです</xsl:text>
  </xsl:when>
  <xsl:otherwise>
    <xsl:text>$i は 1より小さいです</xsl:text>
  </xsl:otherwise>
</xsl:choose>

xsl:for-each

select属性内のXPath式で示されるnodesetもしくはsequenceを巡回して処理します。 for-each内では現在の要素はXPath式.で取得できます。 また、for-eachの第1子要素としてxsl:sort要素を置くと、ソートしてから巡回します

<!-- nodeset の巡回 -->
<xsl:for-each select="/foo/bar">
  <xsl:value-of select="@id" /> <!-- 各bar要素のid属性値を出力 -->
</xsl:for-each>
<xsl:for-each select="(3,2,1)">
  <xsl:sort />
  <xsl:value-of select="." /> <!-- 順に 1 2 3 を出力 -->
</xsl:for-each>

12. 呼び出し可能template・ユーザ関数

xsl:template, xsl:call-template

match属性でなく、name属性を指定すれば、呼び出し可能なtemplateを作成できます。 というか、明示的にxsl:call-tempalteで呼び出さないと、動いてくれません。

xsl:apply-templatesと同様、にwith-paramでパラメタを渡せます

<-- ↓呼び出し側 -->
<xsl:template match="/foo">
  <xsl:call-template name="hoge">
    <xsl:with-param name="p1" select="123" />
  </xsl:call-template>
</xsl:template>
<!-- ↓がcallable template -->
<xsl:tempalte name="hoge">
  <xsl:param name="p1" as="xs:integer" />
  <xsl:value-of select="$p1 * 2" />
</xsl:template>

xsl:function

XPath式中で呼び出し可能な関数を定義します。as属性で戻り値の型を指定し、要素内の評価結果が関数の戻り値になります。 ユーザ関数もどこかの名前空間に属していないといけないので注意してください

<-- 呼び出し側 -->
<xsl:template match="/">
<xsl:for-each select="my:func(99)">
  <xsl:value-of select="." /><xsl:text>,</xsl:text>
</xsl:for-each>
</xsl:template>
<!-- xmlns:my  が適切に設定されていると仮定 -->
<xsl:function name="my:func" as="xs:integer*">
  <xsl:param name="p1" as="xs:integer" />
  <!-- 結果がsequenceならxsl:sequenceを使用します -->
  <xsl:sequence select="1 to $p1" />
</xsl:function>

13. 入出力

基本的な入力はスタイルシート呼び出し時に指定されたXML文書ですが、document()関数でXML文書を、unparsed-text()でその他のテキスト文書を読み込むことが出来ます

基本的な出力先はXSLTプロセッサ依存ですが、xsl:result-document要素を使って出力先を指定することができます

<xsl:variable name="w3c" as="document()" select="document('http://www.w3.org')" />
<xsl:variable name="w3c_text" as="xs:string" select="unparsed-text('http://www.w3.org/')" />

<xsl:result-document href="another_output.txt" method="text">
  <xsl:value-of select="$w3c//title" />
  <xsl:value-of select="$w3c_text" />
</xsl:result-document>

また、xsl:importxsl:includeで他のXSLT文書を取り込めたりしますが、適用ルールとかちょっとややこしいので割愛

14. 知っておくと便利なこと

スタイルシートのルート要素を出力結果のルート要素にできる.(<xsl:template match="/"></xsl:template>の子要素として扱われる

<!-- XSLT仕様より引用  -->
<html xsl:version="2.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Expense Report Summary</title>
  </head>
  <body>
    <p>Total Amount: <xsl:value-of select="expense-report/total"/></p>
  </body>
</html>

sequece様のデータに対してaccumulate的なことをしたい場合は、 functionかnamed templateの再帰呼び出しで何とかする。

<xsl:fucntion name="my:sum" as="xs:integer">
  <xsl:param name="n" as="xs:integer*" />
  <xsl:param name="m" as="xs:integer" />
  <xsl:choose>
    <xsl:when test="fn:exists($n)">
      <xsl:value-of select="my:sum(fn:remove($n,1), $n[1] + $m)" />
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$m" />
    </xsl:otherwise>
  </xsl:choose.
</xsl:function>

<!-- 呼び出し -->
<xsl:value-of select="my:sum( (1,3,5,7), 0 )" />

xsl:variable子要素など、仕様で "<-- Sequence Constructor -->"って書いてあるところには、value-ofやsequence等のデータ作成用要素のみならず、for-eachやchoose,apply-templatesなど、制御用のXSLT要素も記述できる。variableの定義中にローカルなvariableを作って云々とかも可能




...疲れた

トラックバック(0)

トラックバックURL: http://floralcompany.jp/mt/mt-tb.cgi/4

コメントする

AUTHOR

  • turugina (虎王 剱奈)
  • E-mail: turugina {at} floralcompany.jp
  • pixiv
  • ニジエ

2014年5月

        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31

アーカイブ

OpenID対応しています OpenIDについて
Powered by Movable Type 5.2.10

- 警 告 -

本サイトにはいわゆる「18禁画像」(イラスト)へのリンクが存在します。 未成年の方や、その手の画像に不快感を覚える方は、 該当記事(「えちぃの」及び「ちょっとえちぃの」カテゴリ) をご覧にならないようお願いいたします。

上記を理解した上で非表示のブログパーツを表示する
あわせて読みたいブログパーツ
ついった
drawr/pixiv/twitpic