CodeZine(コードジン)

特集ページ一覧

今からでも遅くない JAXPを学ぼう!(後編)
XPathとXSLTを掘り下げる

XML文書を他のXML文書に変換する

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2010/06/07 14:00

ダウンロード サンプルコード (3.8 KB)

目次

XSLTとXPathの関数の理解

 XSLTとXPathの関数を使わずにXML文書を変換することは、よほど簡単な変換でない限り難しいものとなります。すべて紹介したいところですが、当記事ではMeigara.xmlからshop.xmlを変換するXSLTスタイルシートの説明中に個別に紹介します。XSLTとXPathの関数についてはXSL Transformations (XSLT) Version 1.0およびXML Path Language (XPath) Version 1.0を参考にしていただければと思います。

XML文書からXML文書への変換

 ツリーとノード、ロケーションパス、関数が理解できればXSLTスタイルシートを記述する準備は整ったと言えます。さっそく、冒頭で紹介したMeigara.xmlからshop.xmlへ変換するXSLTスタイルシートを記述します。リスト3がそのスタイルシートであるXSLTSample02.xslです。

リスト3.XSLTSample02.xsl
001:<?xml version="1.0" encoding="UTF-8"?>
002:<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
003:    <xsl:output method="xml" indent="yes"/>
004:
005:    <xsl:template match="/MEIGARAS">
006:        <xsl:element name="SHOP">
007:        	<xsl:element name="GREETING">
008:        		<xsl:attribute name="OWNER"><xsl:text>tomoharu</xsl:text></xsl:attribute>
009:        		<xsl:text>店主の好みの芋焼酎を厳選しました。</xsl:text>
010:        	</xsl:element>
011:        	<xsl:element name="{local-name(self::node())}">
012:        		<xsl:apply-templates/>
013:        	</xsl:element>
014:        </xsl:element>
015:    </xsl:template>
016:    
017:    <xsl:template match="MEIGARA">
018:    	<xsl:element name="{local-name(self::node())}">
019:    		<xsl:apply-templates select="child::NAME"/>
020:    		<xsl:apply-templates select="child::ABV"/>
021:    		<xsl:apply-templates select="child::VOLUME"/>
022:    		<xsl:apply-templates select="child::PRICE"/>
023:    		<xsl:element name="MANUFACTURER"/>
024:    	</xsl:element>
025:	</xsl:template>
026:	
027:	<xsl:template match="NAME">
028:		<xsl:element name="{local-name(self::node())}">
029:			<xsl:attribute name="KANA"/>
030:			<xsl:value-of select="self::node()"/>
031:    	</xsl:element>
032:	</xsl:template>
033:
034:	<xsl:template match="ABV">
035:		<xsl:element name="{local-name(self::node())}">
036:			<xsl:attribute name="UNIT"><xsl:text>%</xsl:text></xsl:attribute>
037:			<xsl:value-of select="self::node()"/>
038:		</xsl:element>
039:	</xsl:template>
040:	
041:	<xsl:template match="VOLUME">
042:		<xsl:element name="{local-name(self::node())}">
043:			<xsl:attribute name="UNIT"><xsl:text>ml</xsl:text></xsl:attribute>
044:			<xsl:value-of select="self::node()"/>
045:		</xsl:element>
046:	</xsl:template>
047:
048:	<xsl:template match="PRICE">
049:		<xsl:element name="{local-name(self::node())}">
050:			<xsl:attribute name="UNIT"/>
051:			<xsl:value-of select="self::node()"/>
052:		</xsl:element>
053:	</xsl:template>
054:	
055:</xsl:stylesheet>

 Meigara.xmlからshop.xmlに変換するには、新しい要素の作成と新しい属性の作成の方法を習得するだけです。新しい要素を作るにはxsl:element、新しい属性を作るにはxsl:attribute要素を使用します。

  • 6行目でSHOP要素を作成し、7行目から10行目でGREETING要素とそのOWNER要素を作成しています。7行目から10行目から分かるとおり、xsl:element要素の中でxsl:attribute要素を使用すると、要素とそれに関連する属性を一度に作成できます。また、固定した属性値や要素のテキストを挿入したい場合、xsl:textを使用します。8行目でOWNER属性の値を、9行目でGREETING要素のテキストを挿入しています。
  • 11行目から13行目も要素を作成していますが、入力ツリーの要素名と同じ名称にしたい場合、{local-name(self::node())}のようにname属性を設定します。難しそうに見えますが、local-name()関数はコンテキストノードからノード名を取り出します。引数のself::node()はステップで説明したように軸としてselfを、ノードテキストとしてnode()関数を使っています。実はself::node()は"."という1文字で表すことができます。従ってlocal-name(.)でも構いません。意味としては自分自身のノード名である「MEIGARAS」を取りだしていることになります。当記事では省略形は紹介しませんが、仕様書で確認してください。12行目のxsl:apply-templatesをxsl:element要素を挟むことで、その子孫要素をMEIGARAS要素に挿入できます。
  • 17行目から25行目でMEIGARA要素を作成しています。19行目から22行目でNAME要素、ABV要素、VOLUME要素、PRICE要素を作成するためのテンプレートを呼び出しています。23行目でMANUFACTURER要素を作成しています。
  • 27行目から32行目はNAME要素とKANA属性を作成しています。34行目から39行目でABV要素とUNIT属性を作成しています。41行目から46行目でVOLUME要素とUNIT属性を作成しています。48行目から53行目でPRICE要素とUNIT属性を作成しています。ABV属性の場合は「%」、VOLUME属性の場合、「ml」で固定しているためxsl:textで属性値を設定しています。

  • LINEで送る
  • このエントリーをはてなブックマークに追加

バックナンバー

連載:今からでも遅くない、JAXPを学ぼう!

著者プロフィール

  • 川久保 智晴(カワクボ トモハル)

    haruプログラミング教室(https://haru-idea.jp/)主宰。 COBOL、FORTRANで13年、Javaを中心としたWeb開発で11年。3つしか言語知らないのかというとそうでもなく、sed/awk、Perl、Python, PHP, &nbsp;C#, JavaScript...

あなたにオススメ

All contents copyright © 2005-2021 Shoeisha Co., Ltd. All rights reserved. ver.1.5