ヘッダーをスキップ
Oracle XML DB開発者ガイド
11gリリース1(11.1)
E05669-02
  目次
目次
索引
索引

戻る
戻る
 
次へ
次へ
 

10 XMLTypeデータの変換および検証

この章では、XSLTスタイルシートを使用してXMLTypeデータを変換するための、SQL関数およびXMLType APIについて説明します。また、XML Schemaに対してXMLTypeを検証するために使用可能な様々な関数およびAPIについても説明します。

この章の内容は次のとおりです。

XMLTypeインスタンスの変換

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()

図10-1に、SQLファンクションXMLtransformの構文を示します。この関数は、引数としてXMLTypeインスタンスおよびXSLTスタイルシートを取ります。スタイルシートは、XMLTypeインスタンスまたはVARCHAR2文字列リテラルのいずれかとなります。この関数では、スタイルシートがインスタンスに適用され、XMLTypeインスタンスが戻されます。

図10-1 XMLtransformの構文

図10-1の説明が続きます
「図10-1 XMLtransformの構文」の説明

SQL関数XMLtransformのかわりにXMLTypeメソッドtransform()を使用することもできます。どちらも機能は同じです。

図10-2に、XMLtransformがXSLTスタイルシートを使用してXML文書を変換する方法を示します。この関数は、XSLTスタイルシートで指定されているように、処理された出力をXML、HTMLなどとして戻します。データベースにXMLTypeとして格納されたXML文書の取出しまたは生成を行う場合は、通常、XMLTransformを使用します。

図10-2 XMLTRANSFORMの使用

図10-2の説明が続きます
「図10-2 XMLTRANSFORMの使用」の説明

XMLTRANSFORMおよびXMLType.transform()の例

この項では、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;

XMLTypeインスタンスの検証

多くの場合、特定のXML文書が整形式であることに加えて、特定の文書が特定のXML Schemaに準拠するかどうか(特定のXML Schemaに対して妥当であるかどうか)を認識する必要があります。

デフォルトでは、データベースによってXMLTypeインスタンスが整形式かどうかが確認されます。また、XML Schemaに基づくXMLTypeインスタンスの場合は、データベースによっていくつかの基本的な妥当性チェックが実行されます。完全なXML Schemaの検証(W3Cで指定)はコストがかかる操作のため、XMLTypeインスタンスが構成、格納または取得される場合、これらは完全に検証されません。

XML文書の有効性状態を検証または操作するために、次の関数およびプロシージャが提供されています。

XMLIsValid

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が存在し、このうちのいずれかの要素に対する準拠を確認する場合に有効です。

schemaValidate

PL/SQLプロシージャschemaValidateは、XML Schemaに対してXMLインスタンスがまだ検証されていない場合に、検証を実行します。XML Schemaに基づかない文書の場合は、エラーが発生します。検証に失敗するとエラーが発生しますが、それ以外の場合、文書の状態はVALIDATEDに変更されます。

構文

MEMBER PROCEDURE schemaValidate

isSchemaValidated

PL/SQLファンクションisSchemaValidatedは、XMLTypeインスタンスの検証状態を戻し、XML Schemaに基づくインスタンスがそのスキーマに対して検証されたかどうかを通知します。スキーマに対してインスタンスが検証された場合は1を戻し、それ以外の場合は0(ゼロ)を戻します。

構文

MEMBER FUNCTION isSchemaValidated return NUMBER deterministic

setSchemaValidated

PL/SQLプロシージャsetSchemaValidatedは、入力XMLインスタンスの検証状態を設定します。

構文

MEMBER PROCEDURE setSchemaValidated(flag IN BINARY_INTEGER := 1)

パラメータ:

flagは、検証済の場合は1、検証済でない場合は0(ゼロ)です。デフォルト値は1です。

isSchemaValid

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として格納されたXMLデータの検証例

次の各例に、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;
/

例10-8 チェック制約におけるXMLISVALID PL/SQLファンクションの使用

この例では、次の操作にPL/SQLファンクションXMLIsValidを使用します。

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