14 XSLT Processor for Javaの使用
Extensible Stylesheet Language Transformation (XSLT) Processor for Javaの使用方法について説明します。
14.1 XSLT Processorの概要
次のトピックでは、XSLTを使用したXML変換の前提条件、標準と仕様および概要について説明します。
14.1.1 XSLT Processor for Javaの使用の前提条件
XSLTは、1つのXML文書を別のテキスト文書に変換するために使用できるExtensible Markup Language (XML)に基づいた言語です。たとえば、XSLTを使用してXMLデータ文書を入力として受け取り、文書の要素値に対して算術計算を実行し、計算結果を示すExtensible HyperText Markup Language (XHTML)文書を生成できます。XSLTでは、XPathはソース・ノード・ツリーの要素をナビゲートおよび処理するために使用されます。XPathは、XML文書をノードから構成されるツリーとしてモデル化します。XPathノード・ツリー内のノードのタイプは、DOMツリー内のノードのタイプに対応します。
この章では、次のWorld Wide Web Consortium (W3C)標準を十分に理解していると想定します。
-
Extensible Stylesheet Language (XSL)およびExtensible Stylesheet Language Transformation (XSLT)。XSLTの概要は、「関連ドキュメント」に記載されているXMLの資料を参照してください。
14.1.2 XSLT Processor for Javaの標準および仕様
Oracle XML Developer's Kit (XDK)のXSLTプロセッサは、XSLT2.0勧告をサポートしています。
XPathは、XSLTおよびその他のXML言語で使用されるナビゲーショナル言語であり、XPath 2.0およびXPath 1.0勧告という2つのバージョンがあります。
14.1.3 XSLT 1.0および2.0でのXML変換
Oracle XML Developer's Kit (XDK)はXSLT 1.0に含まれていない便利な機能をいくつか提供しています。XSLT 2.0を使用するには、スタイルシートにversion
属性を設定します。
<? xml-stylesheet version="2.0" ... ?>
XSLT 2.0の便利な機能を次に示します。
-
ユーザー定義関数
<xsl:function>
宣言を使用して関数を定義できます。この要素には、関数名を定義するために1つのname
属性が必要です。name
属性の値はQName
です。<xsl:function>
要素の内容は、関数の形式的な引数を指定する0個以上のxsl:param
要素と、それに続く、関数から戻される値を定義する順序コンストラクタです。QName
はnullの名前空間を持つことができますが、ユーザー定義関数にはnull以外の名前空間が必要です。つまり、abc
が名前空間として定義されている場合、add
は有効なユーザー定義関数ではありませんが、abc:add
は有効なユーザー定義関数です。 -
グループ化
<xsl:for-each-group>
要素、current-group()
関数およびcurrent-grouping-key()
関数を使用して、アイテムをグループ化できます。 -
複数結果文書
<xsl:result-document>
要素を使用して結果ツリーを作成できます。<xsl:result-document>
要素の内容は、ツリーの文書ノードの子に対する順序コンストラクタです。たとえば、この要素を使用すると、XML文書を入力として受け取り、別々の文書に分割できます。書籍のリストを記述するXML文書を受け取り、各書籍に関するXHTML文書を生成できます。次に、各出力文書を検証できます。
-
一時ツリー
XSLT 1.0のようにXSL変換の中間結果とXSL変数を文字列で表現するかわりに、これらを一連の文書ノードとして格納できます。
<xsl:variable>
、<xsl:param>
および<xsl:with-param>
要素で構築できる文書ノードは、一時ツリーと呼ばれます。 -
文字マッピング
XSLT 1.0では、文字のエスケープを指定するには
<xsl:text>
および<xsl:value-of>
要素のdisable-output-escaping
属性を使用する必要がありました。XSLT 2.0では、最上位レベルのstylesheet
要素としてマッピング文字を<xsl:character-map>
要素で宣言できます。この要素を使用して、XSLT出力に<
、>
、&
などの予約文字や無効なXML文字のあるファイルを生成できます。
関連項目:
XSLT 2.0の機能の説明と例はXSL Transformations (XSLT) Version 2.0を参照してください
14.2 XSLT Processor for Javaの使用: 概要
XDK XSLT Processorは、XML文書をXML、HTML、XHTML、プレーン・テキストなどの形式の別のテキストベースの文書に変換します。このプロセッサは、アプリケーション・プログラミング・インタフェース(API)を使用してプログラムから起動することも、コマンドラインから実行することもできます。
XSLT Processorは、次のタスクを実行できます。
-
1つ以上のXSLTスタイルシートを読み取ります。プロセッサは、1つのXML入力文書に複数のスタイルシートを適用し、異なる結果を生成できます。
-
1つ以上の入力XML文書を読み取ります。プロセッサは、1つのスタイルシートを使用して複数のXML入力文書を変換できます。
-
スタイルシートのルールを入力XML文書に適用して、出力文書を構築します。出力は、Document Object Model (DOM)ツリー、出力ストリームまたは一連のSimple API for XML (SAX)イベントです。
XSLTは関数ベースの言語であり、一般に変換を実行するには入力文書およびスタイルシートのDOMを必要としますが、XSLTプロセッサのXDK Java実装は、より少ないリソースで効率的に変換を実行するために、SAXを使用してスタイルシート・オブジェクトを作成できます。このスタイルシート・オブジェクトを再利用して、スタイルシートを再解析せずに複数の文書を変換できます。
14.2.1 XSLT Processor for Javaの使用: 基本プロセス
XSLT Processor for Javaの基本設計を示します。
図14-1は、このプロセスを示しています。
関連項目:
XMLParser
クラスおよびXSDBuilder
クラスの詳細は、Oracle Database XML Java APIリファレンスを参照してください
14.2.2 XSLT Processorのデモ・プログラムの実行
XSLT Processor for Javaのデモ・プログラムは、$ORACLE_HOME/xdk/demo/java/parser/xslt
にあります。
表14-1に、XSLT Processorのテストに使用できるXMLファイルとプログラムを示します。
表14-1 XSLT Processorのサンプル・ファイル
ファイル | 説明 |
---|---|
|
ID選択とパターン・マッチングのテストに使用できるサンプルXML文書。関連付けられているスタイルシートは |
|
|
|
単純な算術の実行に使用できるサンプルXMLデータ文書。関連付けられているスタイルシートは |
|
|
|
ソース・ツリーのナンバリングのテストに使用できるサンプルXMLデータ文書。このXMLデータ文書は書籍の構造を記述します。 |
|
|
|
複合パターンで |
|
|
|
ツリーを後方検索するために |
|
|
|
様々な文字列テストと操作のテストに使用できるサンプルXMLデータ文書。関連付けられているスタイルシートは |
|
|
|
HTMLページのフレームワークを提供するスタイルシート。スタイルシートは |
|
XSL変数の使用のテストに使用できるサンプルXMLデータ文書。このXMLデータ文書は書籍の構造を記述します。関連付けられているスタイルシートは |
|
|
|
Oracle XSLT ProcessorのXSL処理機能の使用方法を簡単な例で示すサンプル・アプリケーション。このプログラムは、入力スタイルシートを使用して入力XML文書を変換します。このプログラムは、XSL変換の結果を ディレクトリ内の任意のXSLTスタイルシートを最初の引数として使用し、関連付けられている |
|
Oracle XSLT ProcessorのXSL処理機能の使用方法を簡単な例で示すサンプル・アプリケーション。このプログラムは、入力スタイルシートを使用して入力XML文書を変換します。このプログラムは、結果をストリームに出力し、 |
サンプル・プログラムのコンパイル方法および実行方法は、README
に示されています。この場合、基本的なステップは次のようになります。
14.2.3 XSLT Processorコマンドライン・ユーティリティの使用
XDKには、複数のXML文書にスタイルシートを適用できるコマンドラインJavaインタフェースであるoraxsl
が含まれています。$ORACLE_HOME/bin/oraxsl
および%ORACLE_HOME%\bin\oraxsl.bat
シェル・スクリプトは、oracle.xml.jaxb.oraxsl
クラスを実行します。
oraxsl
を使用するには、「XDK for Java環境の設定」の説明に従ってCLASSPATH
が設定されていることを確認します。
コマンドラインで次の構文を使用して、oraxsl
を起動します。
oraxsl options source stylesheet result
oraxsl
ユーティリティには、スタイルシート、変換するXMLファイルおよび結果ファイル(オプション)を指定します。結果ファイルを指定しない場合、ユーティリティは変換した文書を標準出力に送信します。複数のXML文書をスタイルシートによって変換する必要がある場合は、-l
または-d
オプションを-s
および-r
オプションとともに使用します。表14-2に、これらのオプションおよび他のオプションを示します。
表14-2 oraxslのコマンドライン・オプション
オプション | 説明 |
---|---|
|
警告を表示します。デフォルトでは、警告はオフになっています。 |
|
プログラムがエラーおよび警告を書き込むファイルを指定します。 |
|
処理するファイルをリストします。 |
|
変換するファイルが格納されているディレクトリを指定します。デフォルトの動作では、ディレクトリ内のすべてのファイルが処理されます。そのディレクトリ内にあるファイルのサブセットのみ(1つのファイルのみなど)を処理する必要がある場合は、 |
|
除外するファイルの拡張子を指定します。このオプションは |
|
含めるファイルの拡張子を指定します。このオプションは |
|
スタイルシートを指定します。 |
|
結果に使用する拡張子を指定します。 |
|
結果を保存するディレクトリを指定します。このオプションは、 |
|
パラメータをリストします。 |
|
処理に使用するスレッド数を指定します。複数のスレッドを使用すると、複数の文書を処理する際のパフォーマンスを向上させることができます。 |
|
冗長出力を生成します。プログラムは、デバッグ情報を出力します。この出力は、処理中に発生した問題の追跡に有効な場合があります。 |
|
デバッグ出力を生成します。デフォルトでは、デバッグ・モードは無効になっています。グラフィカル・ユーザー・インタフェース(GUI)版のXSLTデバッガは、Oracle JDeveloperで使用できます。 |
14.2.3.1 XSLT Processorコマンドライン・ユーティリティの使用: 例
$ORACLE_HOME/xdk/demo/java/parser/xslt
にある様々なXMLファイルおよびスタイルシートでoraxsl
をテストできます。
例14-1に、math.xml
のコンテンツを示します。
例14-2に、math.xsl
というXSLTスタイルシートを示します。
これらのファイルに対してoraxsl
ユーティリティを実行して、次の例に示すHTML出力を生成できます。
oraxsl math.xml math.xsl math.htm
例14-3に、出力ファイルmath.htm
を示します。
例14-1 math.xml
<?xml version="1.0"?>
<doc>
<n1>5</n1>
<n2>2</n2>
<div>-5</div>
<mod>2</mod>
</doc>
例14-2 math.xsl
<?xml version="1.0"?><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="doc">
<HTML>
<H1>Test for mod.</H1>
<HR/>
<P>Should say "1": <xsl:value-of select="5 mod 2"/></P>
<P>Should say "1": <xsl:value-of select="n1 mod n2"/></P>
<P>Should say "-1": <xsl:value-of select="div mod mod"/></P>
<P><xsl:value-of select="div or ((mod)) | or"/></P>
</HTML>
</xsl:template>
</xsl:stylesheet
例14-3 math.htm
<HTML>
<H1>Test for mod.</H1>
<HR>
<P>Should say "1": 1</P>
<P>Should say "1": 1</P>
<P>Should say "-1": -1</P>
<P>true</P>
</HTML>
14.3 XMLの変換
このトピックでは、基本的なXSL変換の実行方法および変換からのDOM結果の取得方法について説明します。
14.3.1 基本的なXSL変換の実行
XSLT Processorで使用される基本的なクラスはDOMParser
およびXSLProcessor
です。XSL2Sample.java
デモ・プログラムは、これらのクラスを使用してXSLTスタイルシートでXML文書を変換する方法をわかりやすく示します。
クラスDOMParser
およびXSLProcessor
は、「XSLT Processor for Javaの使用: 概要」で説明されています。
次の基本ステップを使用して、XSLT Processorを使用するJavaプログラムを作成します。
関連項目
14.3.2 XSL変換からのDOM結果の取得
サンプル・プログラムに、XSL変換からの結果を取得する方法を示します。
XSLSample.java
デモ・プログラムは、XSL変換の結果としてoracle.xml.parser.v2.XMLDocumentFragment
オブジェクトを生成する方法を示します。XMLDocumentFragment
はXML文書ツリーの一部を抽出する軽量Document
オブジェクトです。XMLDocumentFragment
クラスは、org.w3c.dom.DocumentFragment
インタフェースを実装します。
XSL2Sample.java
デモ・プログラムは、DocumentFragment
オブジェクトの生成方法を示しています。XMLの変換の基本ステップは、「基本的なXSL変換の実行」で説明したステップと同じです。XSLProcessor.processXSL()
メソッドに渡される引数のみ異なります。XSL2Sample.java
の次のコード部分は、DOMフラグメントを作成して標準出力に出力する方法を示します。
XMLDocumentFragment result = processor.processXSL(xsl, xml); result.print(System.out);
表14-4に、オブジェクトの操作に使用できるXMLDocumentFragment
メソッドの一部を示します。
表14-4 XMLDocumentFragmentメソッド
メソッド | 説明 |
---|---|
|
このノードがElementである場合はその属性を含む |
|
この要素のローカル名を取得します。 |
|
この要素の名前空間URIを取得します。 |
|
現在のノードの直後のノードを取得します。 |
|
ノードの名前を取得します。 |
|
基礎となるオブジェクトの型を表すコードを取得します。 |
|
現在のノードの親を取得します。 |
|
現在のノードの直前のノードを取得します。 |
|
DOMツリーからSAXイベントを報告します。 |
14.4 Oracle XSLT拡張によるプログラミング
このトピックでは、概要、拡張関数の名前空間の指定、Javaメソッドの使用、コンストラクタ拡張関数の使用、および戻り値戻り値拡張関数の使用について説明します。
14.4.1 Oracle XSLT拡張の概要
XSLT 1.0標準では、拡張要素および拡張関数という2種類の拡張を定義しています。XDKに提供されているXSLT処理用の拡張関数を使用すると、XSLT Processorのユーザーは、任意のJavaメソッドをXSLの式から起動できます。Oracle XSLT拡張を使用する場合、次のガイドラインに従います。
-
特定のプログラミング言語でXSLT拡張を定義する場合、この拡張を起動できるXSLT ProcessorでのみXSLTスタイルシートを使用できます。したがって、Javaで定義されている拡張関数を起動できるのは、JavaバージョンのXSLT Processorのみです。
-
組込みXSL関数で特定の問題を解決できない場合のみ、XSLT拡張を使用します。
-
次の項で説明するように、拡張クラスの名前空間は適切なURLから開始する必要があります。
次のOracle拡張関数は特に便利です。
-
<ora:output>
。<ora:output>
は、最上位レベルの要素として、またはXSLテンプレートで使用できます。最上位レベルの要素として使用する場合は、追加のname
属性がある点を除いて<xsl:output>
拡張関数と同様です。テンプレートとして使用されている場合は、追加属性use
およびhref
があります。この関数は、1つのXSL変換から複数の出力を作成するときに役立ちます。 -
<ora:node-set>
。結果ツリーのフラグメントをnode-setに変換します。この関数は、XSL内の既存のテキストまたは中間テキストの結果を参照してさらに変換する必要がある場合に役立ちます。
14.4.2 XSLT拡張関数の名前空間の指定
Oracle Java拡張関数は、Universal Resource Identifier (URI) http://www.oracle.com/XSL/Transform/java/
に対応する名前空間に属しています。この名前空間に属する拡張関数は、http://www.oracle.com/XSL/Transform/java/classname
の形式でURIを作成できるようにJava classname
のメソッドを参照します。
たとえば、名前空間http://www.oracle.com/XSL/Transform/java/java.lang.String
を使用して、XSL式からjava.lang.String
メソッドを起動できます。
注意:
xsl
接頭辞を名前空間に割り当てる場合、適切なURIはxmlns:xsl="http://www.w3.org/1999/XSL/Transform"
です。その他のURIでは正しい出力を生成できません。
14.4.3 XSLTでのstaticおよび非static Javaメソッドの使用
Javaメソッドがクラスの非staticメソッドの場合、最初のパラメータはメソッドが起動されるインスタンスとして使用され、残りのパラメータがメソッドに渡されます。ただし、拡張関数がstaticメソッドの場合、その拡張関数のすべてのパラメータが、静的関数へのパラメータとして渡されます。
例14-4に、XSLTスタイルシートでのjava.lang.Math.ceil()
メソッドの使用例を示します。
たとえば、例14-4をスタイルシートceil.xsl
として作成し、任意の整形式XML文書に適用できます。たとえば、次のようにoraxsl
ユーティリティを実行します。
oraxsl ceil.xsl ceil.xsl ceil.out
出力文書ceil.out
のコンテンツは次のとおりです。
<?xml version = '1.0' encoding = 'UTF-8'?> 13
注意:
XSLクラス・ローダーは、静的に追加されたJARおよびCLASSPATH
のパス、wrapper.classpath
によって指定されたパスのみ認識します。動的に追加されたファイルはXSLT Processorで認識されません。
例14-4 XSLTスタイルシートでの静的関数の使用
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:math="http://www.oracle.com/XSL/Transform/java/java.lang.Math"> <xsl:template match="/"> <xsl:value-of select="math:ceil('12.34')"/> </xsl:template> </xsl:stylesheet>
14.4.4 コンストラクタ拡張関数の使用
拡張関数new
は、クラスの新しいインスタンスを作成し、コンストラクタとして動作します。
例14-5では、Hello World
という値を持つ新しいString
オブジェクトを作成し、それをXSL変数str1
に格納し、大文字で出力します。
たとえば、このスタイルシートをhello.xsl
として作成し、任意の整形式XML文書に適用できます。たとえば、次のようにoraxsl
ユーティリティを実行します。
oraxsl hello.xsl hello.xsl hello.out
出力文書hello.out
のコンテンツは次のとおりです。
<?xml version = '1.0' encoding = 'UTF-8'?> HELLO WORLD
例14-5 XSLTスタイルシートでのコンストラクタの使用
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:jstring="http://www.oracle.com/XSL/Transform/java/java.lang.String"> <xsl:template match="/"> <!-- creates a new java.lang.String and stores it in the variable str1 --> <xsl:variable name="str1" select="jstring:new('HeLlO wOrLd')"/> <xsl:value-of select="jstring:toUpperCase($str1)"/> </xsl:template> </xsl:stylesheet>
14.4.5 戻り値拡張関数の使用
拡張関数の結果は、XSLに定義されている次の5つの型、およびXSLT 2.0で定義されている単純なXML Schemaデータ型を含むどの型でも出力できます。
-
NodeSet
-
Boolean
-
String
-
Number
-
ResultTree
これらのデータ型は、変数に格納したり、他の拡張関数に渡したりできます。結果の型がXSLに定義されている5つの型のうちの1つである場合、XSLの式の結果として戻すことができます。
XSLT Processorは、パラメータ数と型に基づくオーバーロードをサポートします。プロセッサは、XSLに定義されたとおりに5つのXSL型の間で暗黙的な型変換を実行します。次のデータ型間で型変換を暗黙的に実行します。また、NodeSet
から次のデータ型にも変換します。
-
String
-
Number
-
Boolean
-
ResultTree
相互に暗黙的な変換が可能な2つの型に基づくオーバーロードは許可されません。次のオーバーロードでは、String
およびNumber
は相互に暗黙的な変換が可能なため、XSLでエラーが発生します。
-
overloadme(int i){}
-
overloadme(String s){}
XSLデータ型とJavaデータ型間のマッピングは次のように行われます。
String -> java.lang.String Number -> int, float, double Boolean -> boolean NodeSet -> NodeList ResultTree -> XMLDocumentFragment
例14-6のスタイルシートは、$ORACLE_HOME/xdk/demo/java/parser/xslt
ディレクトリにあるvariable.xml
文書を解析し、<chapter>
要素の子である<title>
の値を取得します。
例14-6をgettitle.xsl
として作成し、次のようにoraxsl
を実行できます。
oraxsl gettitle.xsl gettitle.xsl variable.out
出力文書variable.out
のコンテンツは次のとおりです。
<?xml version = '1.0' encoding = 'UTF-8'?> The value of the title element is: Section Tests
例14-6 gettitle.xsl
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:parser = "http://www.oracle.com/XSL/Transform/java/oracle.xml.parser.v2.DOMParser" xmlns:document = "http://www.oracle.com/XSL/Transform/java/oracle.xml.parser.v2.XMLDocument"> <xsl:template match ="/"> <!-- Create a new instance of the parser and store it in myparser variable --> <xsl:variable name="myparser" select="parser:new()"/> <!-- Call an instance method of DOMParser. The first parameter is the object. The PI is equivalent to $myparser.parse('file:/my_path/variable.xml'). Note that you should replace my_path with the absolute path on your system. --> <xsl:value-of select="parser:parse($myparser, 'file:/my_path/variable.xml')"/> <!-- Get the document node of the XML Dom tree --> <xsl:variable name="mydocument" select="parser:getDocument($myparser)"/> <!-- Invoke getelementsbytagname on mydocument --> <xsl:for-each select="document:getElementsByTagName($mydocument,'chapter')"> The value of the title element is: <xsl:value-of select="docinfo/title" /> </xsl:for-each> </xsl:template> </xsl:stylesheet>
14.5 XML変換のヒントと方法
このトピックでは、XML文書とXSLTのマージ、およびデータベース表の列に基づくHTML入力フォームの作成について説明します。
14.5.1 XML文書とXSLTのマージ
次の例に、XSLTを使用してXML文書をマージする方法を示します。
「appendChild()を使用した文書のマージ」では、DOMでの文書のマージ方法について説明しています。マージ操作が単純な場合、XSLTベースの方法も使用できます。たとえば、例14-7および例14-8に示すXML文書をマージできます。
例14-9に、一致する<key/>
要素値に基づいて、2つのXML文書をマージするサンプル・スタイルシートを示します。
例14-7、例14-8および例14-9のXMLファイルを作成し、これをコマンドラインで実行します。
oraxsl msg_w_num.xml msgmerge.xsl msgmerge.xml
例14-10に、出力文書を示します。この文書は、msg_w_num.xml
およびmsg_w_text.xml
に含まれるデータをマージします。
この方法は、サイズが大きいファイルの場合は、2つの表間での同等のデータベースの結合ほど効果的ではありませんが、XMLファイルのみの場合は有用です。
例14-7 msg_w_num.xml
<messages> <msg> <key>AAA</key> <num>01001</num> </msg> <msg> <key>BBB</key> <num>01011</num> </msg> </messages>
例14-8 msg_w_text.xml
<messages> <msg> <key>AAA</key> <text>This is a Message</text> </msg> <msg> <key>BBB</key> <text>This is another Message</text> </msg> </messages>
例14-9 msgmerge.xsl
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output indent="yes"/> <!-- store msg_w_text.xml in doc2 variable --> <xsl:variable name="doc2" select="document('msg_w_text.xml')"/> <!-- match each node in input xml document, that is, msg_w_num.xml --> <xsl:template match="@*|node()"> <!-- copy the current node to the result tree --> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- match each <msg> element in msg_w_num.xml --> <xsl:template match="msg"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> <!-- insert two spaces so indentation is correct in output document --> <xsl:text> </xsl:text> <!-- copy <text> node from msg_w_text.xml into result tree --> <text><xsl:value-of select="$doc2/messages/msg[key=current()/key]/text"/> </text> </xsl:copy> </xsl:template> </xsl:stylesheet>
例14-10 msgmerge.xml
<?xml version = '1.0' encoding = 'UTF-8'?> <messages> <msg> <key>AAA</key> <num>01001</num> <text>This is a Message</text> </msg> <msg> <key>BBB</key> <num>01011</num> <text>This is another Message</text> </msg> </messages>