この章では、XSLTスタイルシートを使用してXMLTypeデータを変換するための、SQL関数およびXMLType APIについて説明します。また、XML Schemaに対してXMLTypeを検証するために使用可能な様々な関数およびAPIについても説明します。
この章の内容は次のとおりです。
XML文書には、構造はありますがフォーマットはありません。XML文書にフォーマットを追加するために、eXtensible Stylesheet Language(XSL)を使用できます。XSLは、XMLセマンティクスを表示する方法を提供します。XSLTを使用すると、XML要素をHTMLなどの他のフォーマット言語またはマークアップ言語にマップできます。
Oracle XML DBでは、Oracle DatabaseのXMLType表、列またはビューに格納されているXMLTypeインスタンスまたはXMLデータは、XSLスタイルシートおよびXMLTypeメソッドtransform()を使用して、HTML、XMLおよびその他のマークアップ言語に(フォーマット)変換できます。このプロセスは、W3CのXSLT 1.0勧告に準拠しています。
XMLTypeインスタンスは、次の方法で変換できます。
データベースでSQL関数XMLTransform(またはXMLTypeメソッドtransform())を使用する。
XSLT Processor for Javaなどの中間層でXDK変換オプションを使用する。
|
注意: PL/SQLパッケージDBMS_XSLPROCESSORは、単一のスタイルシートを複数の文書に適用する便利で効率的な方法を提供します。このパッケージのパフォーマンスは、スタイルシートの解析が1回のみなので、メソッドtransform()のパフォーマンスよりも優れています。 |
|
関連項目:
|
図10-1に、SQLファンクションXMLtransformの構文を示します。この関数は、引数としてXMLTypeインスタンスおよびXSLTスタイルシートを取ります。スタイルシートは、XMLTypeインスタンスまたはVARCHAR2文字列リテラルのいずれかとなります。この関数では、スタイルシートがインスタンスに適用され、XMLTypeインスタンスが戻されます。
SQL関数XMLtransformのかわりにXMLTypeメソッドtransform()を使用することもできます。どちらも機能は同じです。
図10-2に、XMLtransformがXSLTスタイルシートを使用してXML文書を変換する方法を示します。この関数は、XSLTスタイルシートで指定されているように、処理された出力をXML、HTMLなどとして戻します。データベースにXMLTypeとして格納されたXML文書の取出しまたは生成を行う場合は、通常、XMLTransformを使用します。
この項では、SQL関数XMLtransformおよびXMLTypeメソッドtransform()を使用して、XMLTypeとして格納されているXMLデータを様々な形式に変換する方法を例で示します。
例10-1 XML Schemaの登録およびXMLデータの挿入
この例では、この章の他の例を実行するために必要なXML Schemaおよび表を設定します。(ここに示したdeleteSchemaのコールは、XML Schemaの作成前に既存のスキーマがないようにするためのものです。そのようなスキーマが存在しない場合は、deleteSchemaでエラーが発生します。)
BEGIN
-- Delete the schema, if it already exists; otherwise, this produces an error.
DBMS_XMLSCHEMA.deleteSchema('http://www.example.com/schemas/ipo.xsd',4);
END;
/
BEGIN
-- Register the schema
DBMS_XMLSCHEMA.registerSchema('http://www.example.com/schemas/ipo.xsd',
'<schema targetNamespace="http://www.example.com/IPO"
xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:ipo="http://www.example.com/IPO">
<!-- annotation>
<documentation xml:lang="ja">
International Purchase order schema for Example.com
Copyright 2000 Example.com. All rights reserved.
</documentation>
</annotation -->
<element name="purchaseOrder" type="ipo:PurchaseOrderType"/>
<element name="comment" type="string"/>
<complexType name="PurchaseOrderType">
<sequence>
<element name="shipTo" type="ipo:Address"/>
<element name="billTo" type="ipo:Address"/>
<element ref="ipo:comment" minOccurs="0"/>
<element name="items" type="ipo:Items"/>
</sequence>
<attribute name="orderDate" type="date"/>
</complexType>
<complexType name="Items">
<sequence>
<element name="item" minOccurs="0" maxOccurs="unbounded">
<complexType>
<sequence>
<element name="productName" type="string"/>
<element name="quantity">
<simpleType>
<restriction base="positiveInteger">
<maxExclusive value="100"/>
</restriction>
</simpleType>
</element>
<element name="USPrice" type="decimal"/>
<element ref="ipo:comment" minOccurs="0"/>
<element name="shipDate" type="date" minOccurs="0"/>
</sequence>
<attribute name="partNum" type="ipo:SKU" use="required"/>
</complexType>
</element>
</sequence>
</complexType>
<complexType name="Address">
<sequence>
<element name="name" type="string"/>
<element name="street" type="string"/>
<element name="city" type="string"/>
<element name="state" type="string"/>
<element name="country" type="string"/>
<element name="zip" type="string"/>
</sequence>
</complexType>
<simpleType name="SKU">
<restriction base="string">
<pattern value="[0-9]{3}-[A-Z]{2}"/>
</restriction>
</simpleType>
</schema>',
TRUE, TRUE, FALSE);
END;
/
-- Create table to hold XML instance documents
DROP TABLE po_tab;
CREATE TABLE po_tab (id NUMBER, xmlcol XMLType)
XMLType COLUMN xmlcol
XMLSCHEMA "http://www.example.com/schemas/ipo.xsd"
ELEMENT "purchaseOrder";
INSERT INTO po_tab
VALUES(1, XMLType(
'<?xml version="1.0"?>
<ipo:purchaseOrder
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ipo="http://www.example.com/IPO"
xsi:schemaLocation="http://www.example.com/IPO
http://www.example.com/schemas/ipo.xsd"
orderDate="1999-12-01">
<shipTo>
<name>Helen Zoe</name>
<street>121 Broadway</street>
<city>Cardiff</city>
<state>Wales</state>
<country>UK</country>
<zip>CF2 1QJ</zip>
</shipTo>
<billTo>
<name>Robert Smith</name>
<street>8 Oak Avenue</street>
<city>Old Town</city>
<state>CA</state>
<country>US</country>
<zip>95819</zip>
</billTo>
<items>
<item partNum="833-AA">
<productName>Lapis necklace</productName>
<quantity>1</quantity>
<USPrice>99.95</USPrice>
<ipo:comment>Want this for the holidays!</ipo:comment>
<shipDate>1999-12-05</shipDate>
</item>
</items>
</ipo:purchaseOrder>'));
例10-2 XMLTRANSFORMおよびDBURITYPEを使用したスタイルシートの取得
DBURITypeについては、第20章「URIを介したデータのアクセス」で説明します。
DROP TABLE stylesheet_tab;
CREATE TABLE stylesheet_tab(id NUMBER, stylesheet XMLType);
INSERT INTO stylesheet_tab
VALUES (1,
XMLType(
'<?xml version="1.0" ?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="*">
<td>
<xsl:choose>
<xsl:when test="count(child::*) > 1">
<xsl:call-template name="nested"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="name(.)"/>:<xsl:value-of
select="text()"/>
</xsl:otherwise>
</xsl:choose>
</td>
</xsl:template>
<xsl:template match="*" name="nested" priority="-1" mode="nested2">
<b>
<!-- xsl:value-of select="count(child::*)"/ -->
<xsl:choose>
<xsl:when test="count(child::*) > 1">
<xsl:value-of select="name(.)"/>:<xsl:apply-templates
mode="nested2"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="name(.)"/>:<xsl:value-of
select="text()"/>
</xsl:otherwise>
</xsl:choose>
</b>
</xsl:template>
</xsl:stylesheet>'));
SELECT
XMLtransform(x.xmlcol,
DBURIType('/XDB/STYLESHEET_TAB/ROW
[ID=1]/STYLESHEET/text()').getXML()).getStringVal()
AS result
FROM po_tab x;
これにより、次の出力が生成されます(ここでは、読みやすくするためにフォーマット出力で示しています)。
RESULT
---------------------------------------------------------
<td>
<b>ipo:purchaseOrder:
<b>shipTo:
<b>name:Helen Zoe</b>
<b>street:100 Broadway</b>
<b>city:Cardiff</b>
<b>state:Wales</b>
<b>country:UK</b>
<b>zip:CF2 1QJ</b>
</b>
<b>billTo:
<b>name:Robert Smith</b>
<b>street:8 Oak Avenue</b>
<b>city:Old Town</b>
<b>state:CA</b>
<b>country:US</b>
<b>zip:95819</b>
</b>
<b>items:</b>
</b>
</td>
例10-3 XMLTRANSFORMおよび副問合せを使用したスタイルシートの取得
次に、格納されているスタイルシートを使用して、XMLTypeインスタンスを変換する例を示します。この例では、前述の例と異なり、スカラー副問合せを使用して格納されているスタイルシートを取得します。
SELECT XMLtransform(x.xmlcol,
(SELECT stylesheet FROM stylesheet_tab WHERE id = 1)).getStringVal()
AS result
FROM po_tab x;
例10-4 一時スタイルシートでのメソッドtransform()の使用
この例では、一時スタイルシートを使用したXMLTypeインスタンスの変換においてXMLTypeメソッドtransform()を使用します。
SELECT x.xmlcol.transform(XMLType(
'<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="*">
<td>
<xsl:choose>
<xsl:when test="count(child::*) > 1">
<xsl:call-template name="nested"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="name(.)"/>:<xsl:value-of select="text()"/>
</xsl:otherwise>
</xsl:choose>
</td>
</xsl:template>
<xsl:template match="*" name="nested" priority="-1" mode="nested2">
<b>
<!-- xsl:value-of select="count(child::*)"/ -->
<xsl:choose>
<xsl:when test="count(child::*) > 1">
<xsl:value-of select="name(.)"/>:<xsl:apply-templates mode="nested2"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="name(.)"/>:<xsl:value-of select="text()"/>
</xsl:otherwise>
</xsl:choose>
</b>
</xsl:template>
</xsl:stylesheet>'
)).getStringVal()
FROM po_tab x;
多くの場合、特定のXML文書が整形式であることに加えて、特定の文書が特定のXML Schemaに準拠するかどうか(特定のXML Schemaに対して妥当であるかどうか)を認識する必要があります。
デフォルトでは、データベースによってXMLTypeインスタンスが整形式かどうかが確認されます。また、XML Schemaに基づくXMLTypeインスタンスの場合は、データベースによっていくつかの基本的な妥当性チェックが実行されます。完全なXML Schemaの検証(W3Cで指定)はコストがかかる操作のため、XMLTypeインスタンスが構成、格納または取得される場合、これらは完全に検証されません。
XML文書の有効性状態を検証または操作するために、次の関数およびプロシージャが提供されています。
PL/SQLファンクションXMLIsValidは、入力インスタンスが、指定されたXML Schemaに準拠しているかどうかを確認します。XMLインスタンスの検証状態は変更されません。XML SchemaのURLが指定されておらず、XML文書がXML Schemaに基づく場合は、XMLTypeインスタンス独自のスキーマに対して準拠しているかどうかが確認されます。いずれかの引数がNULLに指定されている場合、結果はNULLになります。検証に失敗すると、0(ゼロ)が戻されますが、その理由を説明するエラーは通知されません。
構文
XMLIsValid (XMLType_inst [, schemaurl [, elem]])
パラメータ:
XMLType_inst - 指定されたXML Schemaに対して検証するXMLTypeインスタンス。
schurl - 準拠を確認するXML Schema URL。
elem - 指定されたスキーマの検証対象要素。複数の最上位要素を定義するXML Schemaが存在し、このうちのいずれかの要素に対する準拠を確認する場合に有効です。
PL/SQLプロシージャschemaValidateは、XML Schemaに対してXMLインスタンスがまだ検証されていない場合に、検証を実行します。XML Schemaに基づかない文書の場合は、エラーが発生します。検証に失敗するとエラーが発生しますが、それ以外の場合、文書の状態はVALIDATEDに変更されます。
構文
MEMBER PROCEDURE schemaValidate
PL/SQLファンクションisSchemaValidatedは、XMLTypeインスタンスの検証状態を戻し、XML Schemaに基づくインスタンスがそのスキーマに対して検証されたかどうかを通知します。スキーマに対してインスタンスが検証された場合は1を戻し、それ以外の場合は0(ゼロ)を戻します。
構文
MEMBER FUNCTION isSchemaValidated return NUMBER deterministic
PL/SQLプロシージャsetSchemaValidatedは、入力XMLインスタンスの検証状態を設定します。
構文
MEMBER PROCEDURE setSchemaValidated(flag IN BINARY_INTEGER := 1)
パラメータ:
flagは、検証済の場合は1、検証済でない場合は0(ゼロ)です。デフォルト値は1です。
PL/SQLファンクションisSchemaValidは、入力インスタンスが、指定されたXML Schemaに準拠しているかどうかを確認します。XMLインスタンスの検証状態は変更されません。XML SchemaのURLが指定されておらず、XML文書がXML Schemaに基づく場合は、XMLTypeインスタンス独自のスキーマに対して準拠しているかどうかが確認されます。検証に失敗すると例外が発生し、その理由が示されます。
構文
MEMBER FUNCTION isSchemaValid(schurl IN VARCHAR2 := NULL, elem IN VARCHAR2 := NULL) RETURN NUMBER DETERMINISTIC
パラメータ:
schurl - 準拠を確認するXML Schema URL。
elem - 指定されたスキーマの検証対象要素。複数の最上位要素を定義するXML Schemaが存在し、このうちのいずれかの要素に対する準拠を確認する場合に有効です。
次の各例に、XMLTypeメソッドisSchemaValid()とschemaValidate()およびPL/SQLファンクションXMLIsValidを使用して、Oracle XML DBにXMLTypeとして格納されているXMLデータを検証する方法を示します。
例10-5 メソッドisSchemaValid()の使用
SELECT x.xmlcol.isSchemaValid('http://www.example.com/schemas/ipo.xsd',
'purchaseOrder')
FROM po_tab x;
例10-6 メソッドisSchemaValid()を使用したXMLの検証
次のPL/SQLの例では、XML Schema PO.xsdに対してXMLインスタンスを検証します。
DECLARE
xmldoc XMLType;
BEGIN
-- Populate xmldoc (for example, by fetching from table).
-- Validate against XML schema
xmldoc.isSchemaValid('http://www.oracle.com/PO.xsd');
IF xmldoc.isSchemaValid = 1 THEN --
ELSE --
END IF;
END;
例10-7 トリガー内でのメソッドschemaValidate()の使用
XMLTypeメソッドschemaValidate()をINSERTおよびUPDATE TRIGGERS内で使用すると、表に格納されているすべてのインスタンスがXML Schemaに対して検証されたことを確認できます。
DROP TABLE po_tab; CREATE TABLE po_tab OF XMLType XMLSCHEMA "http://www.example.com/schemas/ipo.xsd" ELEMENT "purchaseOrder"; CREATE TRIGGER emp_trig BEFORE INSERT OR UPDATE ON po_tab FOR EACH ROW DECLARE newxml XMLType; BEGIn newxml := :new.OBJECT_VALUE; XMLTYPE.schemavalidate(newxml); END; /
XMLTypeインスタンスが指定されたXML Schemaに準拠していることの確認
CHECK制約を使用した、受信したXML文書が妥当であることの確認
DROP TABLE po_tab; CREATE TABLE po_tab OF XMLType (CHECK (XMLIsValid(OBJECT_VALUE) = 1)) XMLSCHEMA "http://www.example.com/schemas/ipo.xsd" ELEMENT "purchaseOrder";
|
注意: 前述の項で示した検証の関数およびプロシージャを使用すると、簡単に妥当性チェックを実行できます。これらのうち、isSchemaValidのみが、エラーの発生時に検証が失敗した理由を示します。 |