この章では、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 のみが、エラーの発生時に検証が失敗した理由を示します。 |