この章では、XSLTスタイル・シートを使用してXMLType
データを変換するための、SQL関数およびXMLType
APIについて説明します。XMLType
インスタンスのXML Schemaに対する検証に使用できる関数およびAPIについても説明します。
この章の内容は次のとおりです。
XML文書には構造はありますが形式はありません。XML文書に形式を追加するには、Extensible Stylesheet Language (XSL)を使用できます。XSLはXMLセマンティクスの表示方法を提供します。XML要素をHTMLなどの他のフォーマット言語またはマークアップ言語にマップできます。
Oracle XML DBでは、Oracle DatabaseのXMLType
表、列またはビューに格納されているXMLType
インスタンスまたはXMLデータは、XSLスタイルシートおよびXMLType
メソッドtransform()
を使用して、HTML、XMLおよびその他のマークアップ言語に(フォーマット)変換できます。このプロセスは、W3CのXSLT 1.0勧告に準拠しています。
XMLType
インスタンスは、次の方法で変換できます。
データベースでOracle SQL関数XMLTransform
(またはXMLType
メソッドtransform()
)を使用する。
XSLT Processor for Javaなどの中間層でOracle XML Developer's Kitの変換オプションを使用する。
図11-1に、Oracle SQL関数XMLtransform
の構文を示します。この関数は引数としてXMLType
インスタンスとXSLTスタイルシートを受け取ります。スタイルシートはXMLType
インスタンスまたはVARCHAR2
文字列リテラルのいずれかです。スタイルシートをインスタンスに適用し、XMLType
インスタンスを戻します。
Oracle SQL関数XMLtransform
のかわりにXMLType
メソッドtransform()
を使用することもできます。どちらも機能は同じです。
図11-2に、XSLTスタイルシートを使用してXMLtransform
がXML文書を変換する方法を示します。XSLTスタイルシートで指定したように、処理された出力をXML、HTMLなどで戻します。データベース内にXMLType
として格納されたXML文書の取得または生成時は、通常はXMLtransform
を使用します。
この項では、Oracle SQL関数XMLtransform
およびXMLTypeメソッド
transform()
を使用して、XMLType
として格納されているXMLデータを様々な形式に変換する方法について説明します。
例11-1では、この章の他の例を実行するために必要なXML Schemaおよび表を設定します。ここに示したdeleteSchema
のコールは、XML Schemaの作成前に既存のスキーマがないようにするためのものです。そのようなスキーマが存在しない場合は、deleteSchema
でエラーが発生します。
例11-1 XML Schemaの登録およびXMLデータの挿入
BEGIN -- Delete the schema, if it already exists. DBMS_XMLSCHEMA.deleteSchema('http://www.example.com/schemas/ipo.xsd',4); END; / BEGIN -- Register the schema DBMS_XMLSCHEMA.registerSchema( SCHEMAURL => 'http://www.example.com/schemas/ipo.xsd', SCHEMADOC => '<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="en"> 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>', LOCAL => TRUE, GENTYPES => TRUE); 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>'));
例11-2に、SQL関数XMLtransform
およびDBURIType
を使用してスタイルシートを取得する方法を示します。DBURIType
の詳細は、第20章「URIを介したデータのアクセス」を参照してください。
例11-2 XMLTRANSFORMおよびDBURITYPEを使用したスタイルシートの取得
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 XMLSerialize(DOCUMENT XMLtransform(x.xmlcol, y.stylesheet) AS varchar2(1000)) AS result FROM po_tab x, stylesheet_tab y WHERE y.id = 1;
これにより、次の出力が生成されます(ここでは、読みやすくするためにフォーマット出力で示しています)。
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>
例11-3に、格納されているスタイルシートを使用して、XMLType
インスタンスを変換する例を示します。例11-3では、例11-2と異なり、格納されているスタイルシートをスカラー副問合せを使用して取得します。
例11-3 XMLTRANSFORMおよび副問合せを使用したスタイルシートの取得
SELECT XMLSerialize(DOCUMENT XMLtransform( x.xmlcol, (SELECT stylesheet FROM stylesheet_tab WHERE id = 1)) AS VARCHAR2(1000)) AS result FROM po_tab x;
例11-4では、一時スタイルシートを使用したXMLType
インスタンスの変換においてXMLTypeメソッド
transform()
を使用します。
例11-4 一時スタイルシートでのメソッドTRANSFORM()の使用
SELECT XMLSerialize( DOCUMENT 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>')) AS varchar2(1000)) FROM po_tab x;
多くの場合、特定のXML文書が整形式であることに加えて、その文書が特定のXML Schemaに準拠するかどうか(特定のXML Schemaに対して妥当であるかどうか)を認識する必要があります。
バイナリXMLとして格納されたXML Schemaに基づくデータは、挿入または更新時に必ず自動的に完全に検証されます。この検証にはDOMの構築は必要ありません。これはストリーミングを使用して実行され、メモリーの使用を効率的にかつ最小限にします。
オブジェクト・リレーショナル形式で格納されるXMLType
データの場合は、完全な検証にDOMの構築が必要なため、メモリー管理の面でコストがかかります。このため、Oracle XML DBは、オブジェクト・リレーショナル形式で格納されるデータが挿入または更新されるときに、完全な検証を自動的には実行しません。
ただし、オブジェクト・リレーショナル形式で格納するためにXMLデータを分解する過程で、Oracle XML DBはXML文書の構造がXML Schemaから導出されたSQLデータ型の定義に準拠しているか確認するため、部分的な検証を実行します。
オブジェクト・リレーショナル形式で格納されたXMLType
データに完全な検証が必要であれば、クライアントで検証してからデータベースに挿入したり、更新することを考慮してください。
XML文書で記録された有効性状態を完全に検証または操作するために、次のものを使用できます。
Oracle SQL関数XMLIsValid
およびXMLType
メソッドIsSchemaValid()
- 検証プロセスを無条件に実行します。検証状態は記録されません。次の値を戻します。
文書が有効と判断される場合は1
。
文書が無効と判断される場合または文書の妥当性が判断できない場合は、0
。
XMLType
メソッドSchemaValidate()
: 検証のステータスが0
(デフォルト)の場合、検証プロセスを実行します。文書が有効だと判断されると、検証ステータスは1
に設定されます(それ以外の場合、ステータスは0
のままです)。
XMLType
メソッドisSchemaValidated()
: XMLType
インスタンスの記録済の検証状態を戻します。
XMLType
メソッドsetSchemaValidated()
: XMLType
インスタンスの検証状態を設定(記録)します。
検証状態では、次のように妥当性がわかります。
1
は、文書が有効と判断されることを示します。
0
は、文書の妥当性が不明であることを示します。検証チェックで文書が無効であるように判断される可能性がありますが、文書が無効であると記録されるわけではありません。検証状態が0
と記録された場合にわかるのは、文書の妥当性が不明であることのみです。
関連項目:
|
この項の各例に、Oracle SQL関数XMLIsValid
と、XMLType
メソッドisSchemaValid()
およびschemaValidate()
を使用して、Oracle XML DBにXMLType
として格納されているXMLデータを検証する方法を示します。
例11-5および例11-6に、PL/SQLメソッドisSchemaValid()
を使用して、XML Schemaに対してXMLインスタンスを検証する方法を示します。
例11-5 SQLでメソッドISSCHEMAVALID()を使用したXMLの検証
SELECT x.xmlcol.isSchemaValid('http://www.example.com/schemas/ipo.xsd',
'purchaseOrder')
FROM po_tab x;
例11-6 PL/SQLでメソッドISSCHEMAVALID()を使用したXMLの検証
DECLARE
xml_instance XMLType;
BEGIN
SELECT x.xmlcol INTO xml_instance FROM po_tab x WHERE id = 1;
IF xml_instance.isSchemaValid('http://www.example.com/schemas/ipo.xsd') = 0
THEN raise_application_error(-20500, 'Invalid Instance');
ELSE DBMS_OUTPUT.put_line('Instance is valid');
END IF;
END;
/
Instance is valid
PL/SQL procedure successfully completed.
XMLType
メソッドschemaValidate()
をINSERT
およびUPDATE
トリガー内で使用すると、表に格納されているすべてのインスタンスがXML Schemaに対して検証されたことを確認できます。例11-7に、これを示します。
例11-7 トリガー内でメソッドSCHEMAVALIDATE()を使用したXMLの検証
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;
/
例11-8では、Oracle SQL関数XMLIsValid
を使用して、次の操作を実行します。
XMLType
インスタンスが指定されたXML Schemaに準拠していることの確認
CHECK
制約を使用した、受信したXML文書が妥当であることの確認
例11-8 CHECK制約内でXMLISVALIDを使用した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";
注意: 「XMLTypeインスタンスの検証」の項で示した検証の関数およびプロシージャを使用すると、簡単に妥当性チェックを実行できます。これらのうち、schemaValidate のみが、エラーの発生時に検証が失敗した理由を示します。 |