この節で説明される関数および擬似関数式は、xml
型の値に対して機能します。
xml
型についての情報は8.13を点検してください。
xml
型のやりとりを変換するxmlparse
およびxmlserialize
擬似関数式はここでは繰り返しません。
これらの多くの関数を使用するには、インストレーションの際configure --with-libxml
付きでビルドされていることが必要です。
SQLデータからXML内容を生成するために関数と擬似関数式の一式が提供されています。 そのようなものとして、クライアントアプリケーションが問い合わせ結果を処理のためXML文書に書式化するのにこれらは特に適しています。
xmlcomment
xmlcomment
(text
)
関数xmlcomment
は指定のテキストを内容とするXMLコメントを含んだXML値を作成します。
結果として構築されるXMLコメントが有効になるよう、テキストは「--
」を含むこと、または「-
」で終結することはできません。
引数がNULLならば結果もNULLになります。
例:
SELECT xmlcomment('hello'); xmlcomment -------------- <!--hello-->
xmlconcat
xmlconcat
(xml
[, ...])
関数xmlconcat
は、個々のXML値のリストを結合し、XMLの内容断片を含む単一の値を作成します。
NULL値は削除され、NULL以外の引数が存在しないときのみ結果はNULLになります。
例:
SELECT xmlconcat('<abc/>', '<bar>foo</bar>'); xmlconcat ---------------------- <abc/><bar>foo</bar>
XML宣言が提示されている場合は次のように組み合わされます。 全ての引数の値が同一のXMLversion宣言を持っていれば、そのversionが結果に使用されます。さもなければversionは使用されません。 全ての引数の値でstandaloneの宣言値が「yes」であれば、その値が結果に使用されます。 全ての引数の値にstandalone宣言値があり、その中で1つでも「no」がある場合、それが結果に使用されます。 それ以外の場合は、結果はstandalone宣言を持ちません。 standalone宣言を必要とするが、standalone宣言がないという結果になった場合には、version 1.0のversion宣言が使用されます。 これはXMLがXML宣言においてversion宣言を含むことを要求するためです。 encoding宣言は無視され、全ての場合で削除されます。
例:
SELECT xmlconcat('<?xml version="1.1"?><foo/>', '<?xml version="1.1" standalone="no"?><bar/>'); xmlconcat ----------------------------------- <?xml version="1.1"?><foo/><bar/>
xmlelement
xmlelement
(namename
[, xmlattributes(value
[ASattname
] [, ... ])] [, content, ...
])
xmlelement
式は与えられた名前、属性、および内容を持つXML要素を生成します。
例:
SELECT xmlelement(name foo); xmlelement ------------ <foo/> SELECT xmlelement(name foo, xmlattributes('xyz' as bar)); xmlelement ------------------ <foo bar="xyz"/> SELECT xmlelement(name foo, xmlattributes(current_date as bar), 'cont', 'ent'); xmlelement ------------------------------------- <foo bar="2007-01-26">content</foo>
有効なXML名ではない要素名と属性名は、シーケンス_x
により障害となる文字を置換することでエスケープされます。ここで、HHHH
_HHHH
は16進数によるその文字のUnicode文字コード番号です。
例をあげます。
SELECT xmlelement(name "foo$bar", xmlattributes('xyz' as "a&b")); xmlelement ---------------------------------- <foo_x0024_bar a_x0026_b="xyz"/>
属性値が列参照の場合、明示的な属性名を指定する必要はありません。この場合、デフォルトで列名が属性名として使用されます。 その他の場合には、属性は明示的な名前で与えられなければなりません。 従って、以下の例は有効です。
CREATE TABLE test (a xml, b xml); SELECT xmlelement(name test, xmlattributes(a, b)) FROM test;
しかし、以下の例は有効ではありません。
SELECT xmlelement(name test, xmlattributes('constant'), a, b) FROM test; SELECT xmlelement(name test, xmlattributes(func(a, b))) FROM test;
もし要素内容が指定されればそのデータ型に従って書式化されます。
もし内容そのものがxml
型であれば、複合XML文書が構築されます。
例をあげます。
SELECT xmlelement(name foo, xmlattributes('xyz' as bar), xmlelement(name abc), xmlcomment('test'), xmlelement(name xyz)); xmlelement ---------------------------------------------- <foo bar="xyz"><abc/><!--test--><xyz/></foo>
そのほかの型の内容は有効なXML文字データにフォーマットされます。
これは特に文字<、>、および&がエンティティに変換されることを意味します。
バイナリデータ(データ型はbytea
)は、設定パラメータxmlbinaryの設定にしたがって、base64もしくは16進符号化方式で表現されます。
個々のデータ型に対する特定の動作は、XMLスキーマ仕様でのSQLおよびPostgreSQLデータ型に調整するため発展すると期待されます。
その時点で記述がより詳細になるでしょう。
xmlforest
xmlforest
(content
[ASname
] [, ...])
xmlforest
式は与えられた名前と内容を使用し、要素のXMLフォレスト(シーケンス)を生成します。
例:
SELECT xmlforest('abc' AS foo, 123 AS bar); xmlforest ------------------------------ <foo>abc</foo><bar>123</bar> SELECT xmlforest(table_name, column_name) FROM information_schema.columns WHERE table_schema = 'pg_catalog'; xmlforest ------------------------------------------------------------------------------------------- <table_name>pg_authid</table_name><column_name>rolname</column_name> <table_name>pg_authid</table_name><column_name>rolsuper</column_name> ...
第2の例に見られるように、内容の値が列参照の場合、要素名は省略可能です。この時は、列名がデフォルトで使用されます。 そうでない時は、名前が指定されなければなりません。
有効なXML名ではない要素名は上のxmlelement
で説明した通りエスケープされます。
同様にして、既にxml
型であるものを除き、内容データは有効なXML内容になるようにエスケープされます。
XMLフォレストは2つ以上の要素からなる場合、有効なXML文書ではないことに注意してください。
したがって、xmlelement
内にxmlforest
式をラップすることが有用なことがあります。
xmlpi
xmlpi
(nametarget
[,content
])
xmlpi
式はXML処理命令を作成します。
内容が存在すれば、その内容は?>
文字シーケンスを含んではなりません。
例:
SELECT xmlpi(name php, 'echo "hello world";'); xmlpi ----------------------------- <?php echo "hello world";?>
xmlroot
xmlroot
(xml
, versiontext
| no value [, standalone yes|no|no value])
xmlroot
式はXML値のルートノードの属性を変更します。
versionが指定されていると、ルートノードのversion宣言での値を変更し、standalone設定が指定されていると、ルートノードのstandalone宣言での値を変更します。
SELECT xmlroot(xmlparse(document '<?xml version="1.1"?><content>abc</content>'), version '1.0', standalone yes); xmlroot ---------------------------------------- <?xml version="1.0" standalone="yes"?> <content>abc</content>
xmlagg
xmlagg
(xml
)
ここで説明している他の関数とは異なり、xmlagg
関数は集約関数です。
これはxmlconcat
が行うように、入力値を連結する集約関数ですが、単一行内の複数の式にまたがった連結ではなく、複数行にまたがった連結を行います。
集約関数についての追加情報は9.20を参照してください。
例:
CREATE TABLE test (y int, x xml); INSERT INTO test VALUES (1, '<foo>abc</foo>'); INSERT INTO test VALUES (2, '<bar/>'); SELECT xmlagg(x) FROM test; xmlagg ---------------------- <foo>abc</foo><bar/>
連結の順序を決定するため、4.2.7に記述されているようにORDER BY
句を集計呼び出しに追加することができます。
以下は例です。
SELECT xmlagg(x ORDER BY y DESC) FROM test; xmlagg ---------------------- <bar/><foo>abc</foo>
下記は以前のバージョンで推奨されていた、非標準的な方法例です。特定のケースでは有用かもしれません。
SELECT xmlagg(x) FROM (SELECT * FROM test ORDER BY y DESC) AS tab; xmlagg ---------------------- <bar/><foo>abc</foo>
この節で記述されている式は、xml
値の属性をチェックします。
IS DOCUMENT
xml
IS DOCUMENT
式IS DOCUMENT
は引数XML値が適切なXML文書であれば真を返し、そうでなければ(つまり、内容の断片)偽を返すか、もしくは引数がNULLであればNULLを返します。
文書と内容の断片の差異については8.13を参照してください。
IS NOT DOCUMENT
xml
IS NOT DOCUMENT
式IS NOT DOCUMENT
は引数XML値が適切なXML文書であれば偽を返し、そうでなければ(つまり、内容の断片)真を返すか、もしくは引数がNULLであればNULLを返します。
XMLEXISTS
XMLEXISTS
(text
PASSING [BY REF]xml
[BY REF])
関数xmlexists
は第一引数のXPath式が何かしらのノードであれば真を返し、そうでなければ偽を返します。
(もしいずれの引数もNULLであった場合はNULLを返します。)
例:
SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY REF '<towns><town>Toronto</town><town>Ottawa</town></towns>'); xmlexists ------------ t (1 row)
BY REF
句は、PostgreSQLには何の影響も与えませんが、他の実装とのSQL互換性や順応性のため、付与することができます。
SQL標準では1つ目のBY REF
を必要としており、2つ目はオプショナルです。
加えてSQL標準ではxmlexists
はXQuery式を第一引数として取る構成としていますが、PostgreSQLでは現在XQueryのサブセットにあたるXPathのみサポートしていることに注意してください。
xml_is_well_formed
xml_is_well_formed
(text
)xml_is_well_formed_document
(text
)xml_is_well_formed_content
(text
)
これらの関数はtext
文字列が整形式かどうかをチェックし、論理値で結果を返します。
xml_is_well_formed_document
は文書が整形式かをチェックし、一方xml_is_well_formed_content
は内容が整形式かをチェックします。
xml_is_well_formed
は、xmloptionパラメータ値がDOCUMENT
に設定されていれば前者を、CONTENT
が設定されていれば後者のチェックを実施します。
これは、xml_is_well_formed
は単純なxml
型へのキャストが成功するかの判断に有用であり、その他の2つの関数はXMLPARSE
の対応による変換が成功するかの判断に有用であることを意味します。
例:
SET xmloption TO DOCUMENT; SELECT xml_is_well_formed('<>'); xml_is_well_formed -------------------- f (1 row) SELECT xml_is_well_formed('<abc/>'); xml_is_well_formed -------------------- t (1 row) SET xmloption TO CONTENT; SELECT xml_is_well_formed('abc'); xml_is_well_formed -------------------- t (1 row) SELECT xml_is_well_formed_document('<pg:foo xmlns:pg="http://postgresql.org/stuff">bar</pg:foo>'); xml_is_well_formed_document ----------------------------- t (1 row) SELECT xml_is_well_formed_document('<pg:foo xmlns:pg="http://postgresql.org/stuff">bar</my:foo>'); xml_is_well_formed_document ----------------------------- f (1 row)
最後の例は、名前空間が正しく一致しているかのチェックも含むことを示しています。
データ型xml
の値を処理するため、PostgreSQLはXPath 1.0式を評価する関数xpath
およびxpath_exists
と、テーブル関数XMLTABLE
を提供しています。
xpath
xpath
(xpath
,xml
[,nsarray
])
関数xpath
は、XML値xml
に対し、XPath式xpath
(ひとつのtext
値)を評価します。そして、XPath式で作成されたノードセットに対応するXML値の配列を返します。
もし、XPath式がノードセットではなくスカラー値を返す場合、単一要素の配列が返されます。
2番目の引数は整形済XML文書でなければなりません。特に、単一のルートノード要素を持たなければなりません。
オプショナルな関数の3番目の引数は名前空間マッピング配列です。
この配列は、第2軸が2に等しい長さをもつ2次元text
配列です(つまり、それは配列の配列で、それぞれは正確に2つの要素からなります)。
それぞれの配列のエントリの最初の要素は名前空間の名前(別名)で、2番目は名前空間のURIです。
この配列内で提供される別名がXML文書自身で使用されるものと同じであることは必要ではありません(言い換えると、XML文書内およびxpath
関数の両方の文脈の中で、別名はローカルです)。
例:
SELECT xpath('/my:a/text()', '<my:a xmlns:my="http://example.com">test</my:a>', ARRAY[ARRAY['my', 'http://example.com']]); xpath -------- {test} (1 row)
デフォルト(匿名)名前空間を取り扱うためには、以下のようなことを実施してください。
SELECT xpath('//mydefns:b/text()', '<a xmlns="http://example.com"><b>test</b></a>', ARRAY[ARRAY['mydefns', 'http://example.com']]); xpath -------- {test} (1 row)
xpath_exists
xpath_exists
(xpath
,xml
[,nsarray
])
関数xpath_exists
は、xpath
関数の特別な形式です。この関数は、XPathを満足する個別のXML値を返す代わりに、問い合わせがそれを満足するかどうかを論理値で返します。
この関数は、名前空間にマッピングされた引数をもサポートする点を除き、標準のXMLEXISTS
述語と同じです。
例:
SELECT xpath_exists('/my:a/text()', '<my:a xmlns:my="http://example.com">test</my:a>', ARRAY[ARRAY['my', 'http://example.com']]); xpath_exists -------------- t (1 row)
xmltable
xmltable
( [XMLNAMESPACES(namespace uri
ASnamespace name
[, ...]), ]row_expression
PASSING [BY REF]document_expression
[BY REF] COLUMNSname
{type
[PATHcolumn_expression
] [DEFAULTdefault_expression
] [NOT NULL | NULL] | FOR ORDINALITY } [, ...] )
xmltable
関数は、与えられたXML値、行を抽出するXPathフィルタ、オプションの列定義の集合に基づいてテーブルを生成します。
オプションのXMLNAMESPACES
句はカンマで区切られた名前空間のリストです。
これは文書とその別名で使用されるXML名前空間を指定します。
デフォルトの名前空間指定は現在のところサポートされていません。
必須のrow_expression
引数はXPath式で、指定のXML文書に対して評価され、XMLノードの順序付きシーケンスが取得されます。
このシーケンスがxmltable
により出力行に変換されます。
document_expression
は演算の対象となるXML文書を提供します。
BY REF
句はPostgreSQLでは何の効果もありませんが、SQL準拠および他の実装との互換性のために受け入れられます。
引数は整形されたXMLドキュメントでなければならず、フラグメントやフォレストは受け付けられません。
必須のCOLUMNS
句は、出力テーブルの列のリストを指定します。
COLUMNS
句を省略した場合、結果集合の行にはxml
型の列が1つだけ含まれ、そこにはrow_expression
にマッチしたデータが含まれます。
COLUMNS
が指定された場合、各エントリは一つの列を表します。
形式については上記の構文サマリーを参照してください。
列名と型は必須ですが、パス、デフォルト値、NULLを許すかどうかの句は省略できます。
FOR ORDINALITY
と印がつけられた列には、元の入力XMLドキュメントの中に現れた出力行の順序に対応する行番号が入ります。
FOR ORDINALITY
の印が付けられるのは最大でも1列です。
列のcolumn_expression
はXPath式で、row_expression
の結果に対応する各行について評価されて、列の値を得ます。
column_expression
が与えられなかった場合は、暗示的なパスとして列名が使用されます。
列のXPath式が複数の要素を戻した場合、エラーが発生します。
式が空のタグとマッチした場合、結果は空文字列となります(NULL
ではありません)。
xsi:nil
の属性はすべて無視されます。
column_expression
にマッチしたXMLのテキスト本体が列の値として使用されます。
要素内の複数のtext()
ノードは順番に結合されます。
子要素、処理命令、コメントはすべて無視されますが、子要素のテキストコンテンツは結果に結合されます。
2つの非テキスト要素間にある空白文字のみのtext()
ノードは保存されること、またtext()
ノードの先頭にある空白文字は削られないことに注意してください。
パス式が行とマッチせず、default_expression
が指定されている場合は、その式を評価した結果の値が使用されます。
その列にDEFAULT
句が指定されていない場合は、そのフィールドはNULL
に設定されます。
default_expression
は列リスト内でそれより前に現れる出力列の値を参照して、ある列のデフォルト値を他の列の値に基づくものにすることができます。
列にはNOT NULL
の印をつけることができます。
NOT NULL
の列のcolumn_expression
が何にもマッチせず、DEFAULT
がない、あるいはdefault_expression
の評価結果もNULLになるという場合はエラーが報告されます。
PostgreSQLの通常の関数とは異なり、column_expression
とdefault_expression
は関数を呼び出す前には単純な値に評価されません。
column_expression
は通常は一つの入力行に対してちょうど一度だけ評価され、default_expression
はフィールドにデフォルト値が必要になる度に評価されます。
式が安定(stable)または不変(immutable)とみなされる場合、評価は繰り返し行われないかもしれません。
実際上、xmltable
は関数呼び出しとしてよりも、副問合せのように動作します。
これはdefault_expression
の中でnextval
のような揮発性(volatile)の関数を有効に使用できること、またcolumn_expression
はXML文書の他の部分に依存するかもしれないということを意味します。
例:
CREATE TABLE xmldata AS SELECT xml $$ <ROWS> <ROW id="1"> <COUNTRY_ID>AU</COUNTRY_ID> <COUNTRY_NAME>Australia</COUNTRY_NAME> </ROW> <ROW id="5"> <COUNTRY_ID>JP</COUNTRY_ID> <COUNTRY_NAME>Japan</COUNTRY_NAME> <PREMIER_NAME>Shinzo Abe</PREMIER_NAME> <SIZE unit="sq_mi">145935</SIZE> </ROW> <ROW id="6"> <COUNTRY_ID>SG</COUNTRY_ID> <COUNTRY_NAME>Singapore</COUNTRY_NAME> <SIZE unit="sq_km">697</SIZE> </ROW> </ROWS> $$ AS data; SELECT xmltable.* FROM xmldata, XMLTABLE('//ROWS/ROW' PASSING data COLUMNS id int PATH '@id', ordinality FOR ORDINALITY, "COUNTRY_NAME" text, country_id text PATH 'COUNTRY_ID', size_sq_km float PATH 'SIZE[@unit = "sq_km"]', size_other text PATH 'concat(SIZE[@unit!="sq_km"], " ", SIZE[@unit!="sq_km"]/@unit)', premier_name text PATH 'PREMIER_NAME' DEFAULT 'not specified') ; id | ordinality | COUNTRY_NAME | country_id | size_sq_km | size_other | premier_name ----+------------+--------------+------------+------------+--------------+--------------- 1 | 1 | Australia | AU | | | not specified 5 | 2 | Japan | JP | | 145935 sq_mi | Shinzo Abe 6 | 3 | Singapore | SG | 697 | | not specified
以下の例では、複数のtext()ノードの結合、列名のXPathフィルターとしての使用、空白文字、XMLコメント、処理命令の取扱いを示します。
CREATE TABLE xmlelements AS SELECT xml $$ <root> <element> Hello<!-- xyxxz -->2a2<?aaaaa?> <!--x--> bbb<x>xxx</x>CC </element> </root> $$ AS data; SELECT xmltable.* FROM xmlelements, XMLTABLE('/root' PASSING data COLUMNS element text); element ---------------------- Hello2a2 bbbCC
以下の例では、XMLNAMESPACES
句を使ってXMLドキュメントやXPath式で使われる追加の名前空間のリストを指定する方法を示します。
WITH xmldata(data) AS (VALUES (' <example xmlns="http://example.com/myns" xmlns:B="http://example.com/b"> <item foo="1" B:bar="2"/> <item foo="3" B:bar="4"/> <item foo="4" B:bar="5"/> </example>'::xml) ) SELECT xmltable.* FROM XMLTABLE(XMLNAMESPACES('http://example.com/myns' AS x, 'http://example.com/b' AS "B"), '/x:example/x:item' PASSING (SELECT data FROM xmldata) COLUMNS foo int PATH '@foo', bar int PATH '@B:bar'); foo | bar -----+----- 1 | 2 3 | 4 4 | 5 (3 rows)
以下の関数はリレーショナルテーブルの内容をXML値にマップします。 これらはXMLエクスポート機能と考えることができます。
table_to_xml(tbl regclass, nulls boolean, tableforest boolean, targetns text) query_to_xml(query text, nulls boolean, tableforest boolean, targetns text) cursor_to_xml(cursor refcursor, count int, nulls boolean, tableforest boolean, targetns text)
それぞれの関数の戻り値型はxml
です。
table_to_xml
は、パラメータtbl
として渡された名前付きのテーブルの内容をマップします。
regclass
型はオプションのスキーマ修飾と二重引用符を含む、通常の表記法を使用しテーブルを特定する文字列を受け付けます。
query_to_xml
は、パラメータquery
としてテキストが渡された問い合わせを実行し、結果セットをマップします。
cursor_to_xml
は、パラメータcursor
で指定されたカーソルから提示された行数を取得します。
それぞれの関数により結果値がメモリーに構築されるため、この異形は巨大なテーブルをマップする必要がある場合推奨されます。
tableforest
が偽であれば、結果のXML文書は以下のようになります。
<tablename> <row> <columnname1>data</columnname1> <columnname2>data</columnname2> </row> <row> ... </row> ... </tablename>
tableforest
が真であれば、結果は以下のようなXML文書の断片です。
<tablename> <columnname1>data</columnname1> <columnname2>data</columnname2> </tablename> <tablename> ... </tablename> ...
テーブル名が利用できないとき、つまり、問い合わせ、またはカーソルをマップする時は、最初の書式では文字列table
が使用され、2番目の書式ではrow
が使用されます。
これらどの書式を選択するのかはユーザ次第です。
最初の書式は適切なXML文書で、多くのアプリケーションにおいて重要です。
第2の書式は、後に結果値が1つの文書に再び組み立てられる場合、cursor_to_xml
関数内でより有用になる傾向があります。
上記で説明したXML内容を作成する関数、特にxmlelement
は結果を好みにかえるために使用することができます。
データの値は上記関数xmlelement
で説明したのと同じ方法でマップされます。
パラメータnulls
は出力にNULL値が含まれる必要があるかを決定します。
もし真であれば列内のNULL値は以下のように表現されます。
<columnname xsi:nil="true"/>
ここでxsi
はXMLスキーマインスタンスに対するXML名前空間接頭辞です。
適切な名前空間宣言が結果値に追加されます。
もし偽の場合、NULL値を含む列は単に出力から削除されます。
パラメータtargetns
は結果の希望するXML名前空間を指定します。
特定の名前空間が必要なければ、空文字列を渡す必要があります。
以下の関数は、対応する上記関数により行われたマッピングを記述するXMLスキーマ文書を返します。
table_to_xmlschema(tbl regclass, nulls boolean, tableforest boolean, targetns text) query_to_xmlschema(query text, nulls boolean, tableforest boolean, targetns text) cursor_to_xmlschema(cursor refcursor, nulls boolean, tableforest boolean, targetns text)
一致するXMLデータマッピングとXMLスキーマ文書を取得するため、同じパラメータが渡されることが不可欠です。
以下の関数は、XMLデータマッピングとそれに対応するXMLスキーマがお互いにリンクされた、1つの文書(またはフォレスト)を作成します。 これらは自己完結した、自己記述的な結果を希望する場合に便利です。
table_to_xml_and_xmlschema(tbl regclass, nulls boolean, tableforest boolean, targetns text) query_to_xml_and_xmlschema(query text, nulls boolean, tableforest boolean, targetns text)
さらに、以下の関数がスキーマ全体、または現在のデータベース全体の類似マッピングを作成するため利用できます。
schema_to_xml(schema name, nulls boolean, tableforest boolean, targetns text) schema_to_xmlschema(schema name, nulls boolean, tableforest boolean, targetns text) schema_to_xml_and_xmlschema(schema name, nulls boolean, tableforest boolean, targetns text) database_to_xml(nulls boolean, tableforest boolean, targetns text) database_to_xmlschema(nulls boolean, tableforest boolean, targetns text) database_to_xml_and_xmlschema(nulls boolean, tableforest boolean, targetns text)
これらはメモリー内に作成される必要がある、多くのデータを生成する潜在的可能性があることに注意してください。 巨大なスキーマ、またはデータベースの内容マッピングを要求する際は、その代わりにテーブルを別々にマップすること、さらにはカーソル経由とすることさえ、検討することは無駄ではありません。
スキーマ内容マッピングの結果は以下のようになります。
<schemaname> table1-mapping table2-mapping ... </schemaname>
ここで、テーブルマッピング書式は上で説明したとおりtableforest
パラメータに依存します。
データベース内容マッピング書式は以下のようになります。
<dbname> <schema1name> ... </schema1name> <schema2name> ... </schema2name> ... </dbname>
ここで、スキーママッピングは上記のとおりです。
これらの関数で作成された出力を使用する1つの例として、図 9.1は、テーブルデータの表形式への翻訳を含むtable_to_xml_and_xmlschema
からHTML文書への出力の変換をおこなうXSLTスタイルシートを示します。
同じようにして、これらの関数の結果は他のXML基準書式に変換されます。
図9.1 SQL/XML出力をHTMLに変換するXSLTスタイルシート
<?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.w3.org/1999/xhtml" > <xsl:output method="xml" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" doctype-public="-//W3C/DTD XHTML 1.0 Strict//EN" indent="yes"/> <xsl:template match="/*"> <xsl:variable name="schema" select="//xsd:schema"/> <xsl:variable name="tabletypename" select="$schema/xsd:element[@name=name(current())]/@type"/> <xsl:variable name="rowtypename" select="$schema/xsd:complexType[@name=$tabletypename]/xsd:sequence/xsd:element[@name='row']/@type"/> <html> <head> <title><xsl:value-of select="name(current())"/></title> </head> <body> <table> <tr> <xsl:for-each select="$schema/xsd:complexType[@name=$rowtypename]/xsd:sequence/xsd:element/@name"> <th><xsl:value-of select="."/></th> </xsl:for-each> </tr> <xsl:for-each select="row"> <tr> <xsl:for-each select="*"> <td><xsl:value-of select="."/></td> </xsl:for-each> </tr> </xsl:for-each> </table> </body> </html> </xsl:template> </xsl:stylesheet>