7 XQuery Processor for Javaの使用

Oracle XML Developer's Kit (XDK) XQuery Processor for Javaの使用方法について説明します。

トピック:

7.1 XQuery Processor for Javaの概要

XDKには、Javaアプリケーションで使用するためのスタンドアロンのXQuery プロセッサが用意されています。XQueryは、Extensible Markup Language (XML)用のWorld Wide Web Consortium (W3C)標準問合せ言語です。Javaアプリケーション内でXQueryを使用してXMLを処理することで、開発者の生産性とアプリケーションのパフォーマンスが向上します。

一般に、XQueryで記述されたアプリケーションは、すべてJavaで記述されたアプリケーションよりもコードが少なくなり、高速で実行でき、少しのメモリーしか使用しません。

JSR 225: XQuery API for Java (XQJ)に、Javaアプリケーションから問合せを実行する方法が定義されています。XQJを使用するには、アプリケーションがJavaバージョン1.6で実行されている必要があります。さらに、次のJARファイルも必要です。

  • jlib/oxquery.jar

  • jlib/xqjapi.jar

  • jlib/orai18n-mapping.jar

  • lib/xmlparserv2.jar

  • xdk/jlib/apache-xmlbeans.jar

これらのJava Archive (JAR)ファイルのディレクトリ・パスは、Oracle DatabaseインストールのORACLE_HOMEディレクトリへの相対パスです。

例7-1に、XQuery API for Java (XQJ)を使用して簡易な「Hello World」問合せを実行する方法を示します。XQueryプロセッサはJava仮想マシン(JVM)で直接実行されるため、この例を実行するのにデータベースやサーバーは必要ありません。この例では、出力<hello-world>2</hello-world>が生成されます。

この章では、OracleによるXQueryの実装に固有の機能および拡張機能について説明します。このドキュメントでは、XQueryおよびXQJの一般的な情報についてはとりあげません。

関連項目:

注意:

Oracleでは、Oracle XML DBの一部としてもXQueryおよびXQJを実装しています。Oracle XML DBの詳細は、「XQuery API for Javaを使用したOracle XML DBへのアクセス」を参照してください。

例7-1 XQJを使用した簡易な問合せ

import javax.xml.xquery.XQConnection;
import javax.xml.xquery.XQException;
import javax.xml.xquery.XQPreparedExpression;
import javax.xml.xquery.XQSequence;
 
import oracle.xml.xquery.OXQDataSource;
 
public class HelloWorld {
    
    public static void main(String[] args) throws XQException {
        OXQDataSource ds = new OXQDataSource();
        XQConnection con = ds.getConnection();
        String query = "<hello-world>{1 + 1}</hello-world>";
        XQPreparedExpression expr = con.prepareExpression(query);
        XQSequence result = expr.executeQuery();

        // prints "<hello-world>2</hello-world>"
        System.out.println(result.getSequenceAsString(null));
        
        result.close();
        expr.close();
        con.close();
    }
    
}

7.2 XQJエンティティの解決

XDKでは、問合せ処理中にドキュメント、スキーマ、モジュール、照合および外部関数を取得する方法を制御するために、エンティティ・リゾルバ・フレームワークによってXQJを拡張しています。この項の各例で、複数のタイプのエンティティにエンティティ・リゾルバを使用する方法を示します。

問合せプロセッサがリクエストできるエンティティ・タイプの完全なリストについては、Oracle Database XML Java APIリファレンスのクラスoracle.xml.xquery.OXQEntityに関する項を参照してください。

トピック:

7.2.1 fn:docのドキュメントの解決

この項の例では、エンティティ・リゾルバを使用してXQuery関数fn:docから返されるドキュメントを特定する方法を示します。

例7-2に、books.xmlの内容を示します。

例7-3に、books.xqの内容を示します。

例7-4に、カスタム・エンティティ・リゾルバを使用して問合せbooks.xqを実行する方法を示します。

接続に設定することで、MyEntityResolverのインスタンスがXQueryプロセッサに渡されます。XQueryプロセッサは問合せ処理中にエンティティ・リゾルバを起動して、fn:doc関数から返されるドキュメントを取得します。

例7-2 books.xml

<books>
  <book>
    <title>A Game of Thrones</title>
    <author><first>George</first><last>Martin</last></author>
    <price>10.99</price>
  </book>
  <book>
    <title>The Pillars of the Earth</title>
    <author><first>Ken</first><last>Follett</last></author>
    <price>7.99</price>
  </book>
</books>

例7-3 books.xq

for $book in fn:doc('books.xml')/books/book 
where xs:decimal($book/price) gt 10.00
return
  $book/title

例7-4 カスタム・エンティティ・リゾルバを使用した問合せの実行

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URI;
 
import javax.xml.xquery.XQConnection;
import javax.xml.xquery.XQException;
import javax.xml.xquery.XQPreparedExpression;
import javax.xml.xquery.XQSequence;
import javax.xml.xquery.XQStaticContext;
 
import oracle.xml.xquery.OXQConnection;
import oracle.xml.xquery.OXQDataSource;
import oracle.xml.xquery.OXQEntity;
import oracle.xml.xquery.OXQEntityKind;
import oracle.xml.xquery.OXQEntityLocator;
import oracle.xml.xquery.OXQEntityResolver;
import oracle.xml.xquery.OXQEntityResolverRequestOptions;
import oracle.xml.xquery.OXQView;

public class ResolveDocument {
 
    private static class MyEntityResolver extends OXQEntityResolver {
        @Override
        public OXQEntity resolveEntity(OXQEntityKind kind, OXQEntityLocator locator,
                OXQEntityResolverRequestOptions options) throws IOException {
            if (kind == OXQEntityKind.DOCUMENT) {
                URI systemId = locator.getSystemIdAsURI();
                if ("file".equals(systemId.getScheme())) {
                    File file = new File(systemId);
                    FileInputStream input = new FileInputStream(file);
                    OXQEntity result = new OXQEntity(input);
                    result.enlistCloseable(input);
                    return result;
                }
            }
            return null;
        }
    }
 
    public static void main(String[] args) throws XQException, IOException {
        OXQDataSource ds = new OXQDataSource();
        XQConnection con = ds.getConnection();
 
        // OXQView is used to access Oracle extensions on XQJ objects.
        OXQConnection ocon = OXQView.getConnection(con);
        ocon.setEntityResolver(new MyEntityResolver());
 
        File query = new File("books.xq");
        
        // Relative URIs are resolved against the base URI before invoking the entity resolver.
        // The relative URI 'books.xml' used in the query will be resolved against this URI.
        XQStaticContext ctx = con.getStaticContext();
        ctx.setBaseURI(query.toURI().toString());
 
        FileInputStream queryInput = new FileInputStream(query);
        XQPreparedExpression expr = con.prepareExpression(queryInput, ctx);
        queryInput.close();
        XQSequence result = expr.executeQuery();

        // Prints "<title>A Game of Thrones</title>"
        System.out.println(result.getSequenceAsString(null));
        
        result.close();
        expr.close();
        con.close();
    }
}

次の出力が生成されます。

<title>A Game of Thrones</title>

7.2.2 XQuery外部関数の解決

エンティティ・リゾルバを使用して、XQuery外部関数の実装を定義できます。

問合せで宣言されるXQuery外部関数ごとに、oracle.xml.xquery.OXQEntityKind.EXTERNAL_FUNCTIONという種類のエンティティを使用してエンティティ・リゾルバがコールされます。コールでエンティティ・リゾルバに渡されるoracle.xml.xquery.OXQEntityLocatorインスタンスにより、XQuery関数の名前とその引数のタイプが指定されます。エンティティ・リゾルバは、publicコンストラクタを持ち、oracle.xml.xquery.OXQFunctionEvaluatorを拡張する任意のクラスを返すことができます。その後、XQueryプロセッサは返されたクラスをインスタンス化します。XQuery外部関数コールが評価される際、メソッドevaluate()が起動されます。

例7-5に、ファイルtrim.xqの内容であるXQuery問合せを示します。

外部XQuery関数util:trimは、文字列値の先頭および末尾から空白を削除します。この関数はJavaに実装されており、問合せ内でコールされます。

例7-6では、trim.xqを使用して、外部XQuery関数の実装を定義する方法を示します。この例では、エンティティ・リゾルバはOXQFunctionEvaluatorを拡張するクラスを返します。

クラスではなくJava静的メソッドを返すほうが便利な場合もあります。静的メソッドが返されると、問合せプロセッサは自動的にメソッド引数をマップして、XQJ仕様で定義されたとおりに、値をXQueryデータ・モデルに返します。

例7-7では、trim.xqも実行しますが、今回はJava静的メソッドに外部関数がバインドされています。

例7-5 trim.xq

declare namespace util = "http://example.com/util";
 
declare function util:trim($arg as xs:string) as xs:string external;
 
(: a string with surrounding white space :)
declare variable $input := "   John Doe    ";
 
<result>{util:trim($input)}</result>

例7-6 外部XQuery関数の実装の定義

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Collections;
 
import javax.xml.namespace.QName;
import javax.xml.xquery.XQConnection;
import javax.xml.xquery.XQException;
import javax.xml.xquery.XQPreparedExpression;
import javax.xml.xquery.XQSequence;
 
import oracle.xml.xquery.OXQConnection;
import oracle.xml.xquery.OXQDataSource;
import oracle.xml.xquery.OXQEntity;
import oracle.xml.xquery.OXQEntityKind;
import oracle.xml.xquery.OXQEntityLocator;
import oracle.xml.xquery.OXQEntityResolver;
import oracle.xml.xquery.OXQEntityResolverRequestOptions;
import oracle.xml.xquery.OXQFunctionContext;
import oracle.xml.xquery.OXQFunctionEvaluator;
import oracle.xml.xquery.OXQFunctionMetaData;
import oracle.xml.xquery.OXQView;

public class ResolveExternalFunction {
 
    public static class TrimFunction extends OXQFunctionEvaluator {
        @Override
        public XQSequence evaluate(OXQFunctionContext context, XQSequence[] params) throws XQException {
            XQConnection con = context.getConnection();
            XQSequence arg = params[0];
            String value = arg.getSequenceAsString(null);
            String trimmed = value.trim();
            return con.createSequence(Collections.singleton(trimmed).iterator());
        }
    }
    
    private static class MyEntityResolver extends OXQEntityResolver {
        @Override
        public OXQEntity resolveEntity(OXQEntityKind kind, OXQEntityLocator locator,
                OXQEntityResolverRequestOptions options) throws XQException, IOException {
            if (kind == OXQEntityKind.EXTERNAL_FUNCTION) {
                OXQFunctionMetaData metaData = (OXQFunctionMetaData)locator.getExtension();
                QName name = metaData.getName();
                int arity = metaData.getParameterTypes().length;
                if ("http://example.com/util".equals(name.getNamespaceURI()) &&
                    "trim".equals(name.getLocalPart()) && arity == 1) {
                    return new OXQEntity(TrimFunction.class);
                }
            }
            return null;
        }
    }

    public static void main(String[] args) throws IOException, XQException {
        OXQDataSource ds = new OXQDataSource();
        XQConnection con = ds.getConnection();
        OXQConnection ocon = OXQView.getConnection(con);
        ocon.setEntityResolver(new MyEntityResolver());
 
        FileInputStream query = new FileInputStream("trim.xq");
        XQPreparedExpression expr = con.prepareExpression(query);
        query.close();

        XQSequence result = expr.executeQuery();

        System.out.println(result.getSequenceAsString(null));
 
        result.close();
        expr.close();
        con.close();
    }
}

この例では、出力<result>John Doe</result>が生成されます。

例7-7 外部関数のJava静的メソッドへのバインド

import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Method;
 
import javax.xml.namespace.QName;
import javax.xml.xquery.XQConnection;
import javax.xml.xquery.XQException;
import javax.xml.xquery.XQPreparedExpression;
import javax.xml.xquery.XQSequence;
 
import oracle.xml.xquery.OXQConnection;
import oracle.xml.xquery.OXQDataSource;
import oracle.xml.xquery.OXQEntity;
import oracle.xml.xquery.OXQEntityKind;
import oracle.xml.xquery.OXQEntityLocator;
import oracle.xml.xquery.OXQEntityResolver;
import oracle.xml.xquery.OXQEntityResolverRequestOptions;
import oracle.xml.xquery.OXQFunctionMetaData;
import oracle.xml.xquery.OXQView;

public class ResolveExternalFunction2 {
 
    public static String trim(String value) {
        return value.trim();
    }
    
    private static class MyEntityResolver extends OXQEntityResolver {
        @Override
        public OXQEntity resolveEntity(OXQEntityKind kind, OXQEntityLocator locator,
                OXQEntityResolverRequestOptions options) throws XQException, IOException {
            if (kind == OXQEntityKind.EXTERNAL_FUNCTION) {
                OXQFunctionMetaData metaData = (OXQFunctionMetaData)locator.getExtension();
                QName name = metaData.getName();
                int arity = metaData.getParameterTypes().length;
                if ("http://example.com/util".equals(name.getNamespaceURI()) &&
                    "trim".equals(name.getLocalPart()) && arity == 1) {
                    Method staticMethod = null;
                    try {
                        staticMethod = ResolveExternalFunction2.class.getMethod("trim", String.class); 
                    } catch (NoSuchMethodException e) {
                        throw new IllegalStateException(e);
                    }
                    return new OXQEntity(staticMethod);
                }
            }
            return null;
        }
    }

    public static void main(String[] args) throws IOException, XQException {
        OXQDataSource ds = new OXQDataSource();
        XQConnection con = ds.getConnection();
        OXQConnection ocon = OXQView.getConnection(con);
        ocon.setEntityResolver(new MyEntityResolver());
 
        FileInputStream query = new FileInputStream("trim.xq");
        XQPreparedExpression expr = con.prepareExpression(query);
        query.close();
 
        XQSequence result = expr.executeQuery();

        // Prints "<result>John Doe</result>"
        System.out.println(result.getSequenceAsString(null));
 
        result.close();
        expr.close();
        con.close();
    }
}

この例では、例7-6の場合と同じ出力<result>John Doe</result>が生成されます。

7.2.3 インポートされたXQueryモジュールの解決

エンティティ・リゾルバは、XQueryライブラリ・モジュールによってインポートされたXQueryモジュールを見つけることができます。

XQueryライブラリ・モジュールには、他のモジュールによってインポートできる関数や変数が用意されています。インポートされたモジュールごとに、oracle.xml.xquery.OXQEntityKind.MODULEという種類のエンティティを使用してエンティティ・リゾルバがコールされます。oracle.xml.xquery.OXQEntityLocatorインスタンスを使用してgetSystemId()メソッドを起動し、インポートされるモジュールの場所を取得できます。モジュール・インポートで場所が指定されていない場合、getNamespace()メソッドを起動して、モジュールのターゲット名前空間を取得できます。これにより、エンティティ・リゾルバは対応するライブラリ・モジュールを返すことができます。

この項の例では、エンティティ・リゾルバを使用してXQueryライブラリ・モジュールの解決を制御する方法を示します。

例7-8に、math.xqの内容を示します。

例7-9に、main.xqの内容を示します。

例7-10に、ライブラリ・モジュールをインポートする問合せを実行する方法を示します。

問合せmain.xqはライブラリ・モジュールmath.xqをインポートしてから、関数math:circumferenceを起動して円の円周を計算します。

例7-8 math.xq

module namespace math = "http://example.com/math";
 
declare variable $math:pi as xs:decimal := 3.14159265;
 
declare function math:circumference($diameter as xs:decimal) {
   $math:pi * $diameter
};

例7-9 main.xq

import module namespace math = "http://example.com/math" at "math.xq";
 
math:circumference(6.54)

例7-10 ライブラリ・モジュールをインポートする問合せの実行

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URI;
 
import javax.xml.xquery.XQConnection;
import javax.xml.xquery.XQException;
import javax.xml.xquery.XQPreparedExpression;
import javax.xml.xquery.XQSequence;
import javax.xml.xquery.XQStaticContext;
 
import oracle.xml.xquery.OXQConnection;
import oracle.xml.xquery.OXQDataSource;
import oracle.xml.xquery.OXQEntity;
import oracle.xml.xquery.OXQEntityKind;
import oracle.xml.xquery.OXQEntityLocator;
import oracle.xml.xquery.OXQEntityResolver;
import oracle.xml.xquery.OXQEntityResolverRequestOptions;
import oracle.xml.xquery.OXQView;

public class ResolveLibraryModule {
 
    private static class MyEntityResolver extends OXQEntityResolver {
        @Override
        public OXQEntity resolveEntity(OXQEntityKind kind, OXQEntityLocator locator,
                OXQEntityResolverRequestOptions options) throws IOException {
            if (kind == OXQEntityKind.MODULE) {
                URI systemId = locator.getSystemIdAsURI();
                if (systemId != null && "file".equals(systemId.getScheme())) {
                    File file = new File(systemId);
                    FileInputStream input = new FileInputStream(file);
                    OXQEntity result = new OXQEntity(input);
                    result.enlistCloseable(input);
                    return result;
                }
            }
            return null;
        }
    }

    public static void main(String[] args) throws XQException, IOException {
        OXQDataSource ds = new OXQDataSource();
        XQConnection con = ds.getConnection();
 
        // OXQView is used to access Oracle extensions on XQJ objects.
        OXQConnection ocon = OXQView.getConnection(con);
        ocon.setEntityResolver(new MyEntityResolver());
 
        File query = new File("main.xq");
        
        // Relative URIs are resolved against the base URI before invoking the entity resolver.
        // The relative URI 'math.xq' used in the query will be resolved against this URI.
        XQStaticContext ctx = con.getStaticContext();
        ctx.setBaseURI(query.toURI().toString());
        
        FileInputStream queryInput = new FileInputStream(query);
        XQPreparedExpression expr = con.prepareExpression(queryInput, ctx);
        queryInput.close();

        XQSequence result = expr.executeQuery();

        // Prints the result: "20.546015931"
        System.out.println(result.getSequenceAsString(null));
        
        result.close();
        expr.close();
        con.close();
    }
}

次の出力が生成されます。

20.546015931

7.2.4 XQuery問合せによってインポートされるXMLスキーマの解決

エンティティ・リゾルバを使用して、XQuery問合せによってインポートされるXMLスキーマを制御できます。

XQueryスキーマ・インポートでは、型定義、要素宣言および属性宣言をXMLスキーマからインポートします。インポートされた宣言および定義を問合せで使用して、データ・インスタンスを検証およびテストできます。

例7-11に、XMLスキーマ・ファイルsize.xsdの内容を示します。

例7-12に、XQueryファイルsize.xqの内容を示します。

例7-13に、スキーマをインポートする問合せを実行する方法を示します。

size.xqでは、size.xsdで定義された型shirt-sizeを使用して値リストをテストします。

例7-11 size.xsd

<xs:schema 
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  targetNamespace="http://example.com/size">
 
  <xs:simpleType name="shirt-size">
    <xs:restriction base="xs:string">
      <xs:enumeration value="XS"/>
      <xs:enumeration value="S"/>
      <xs:enumeration value="M"/>
      <xs:enumeration value="L"/>
      <xs:enumeration value="XL"/>
    </xs:restriction>
  </xs:simpleType>
 
</xs:schema>

例7-12 size.xq

import schema namespace ns = "http://example.com/size" at "size.xsd";
 
for $size in ("S", "big", "XL", 42)
return
  if ($size castable as ns:shirt-size) then
    ns:shirt-size($size)
  else
    concat("INVALID:", $size)

例7-13 XMLスキーマをインポートするXQuery問合せの実行

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URI;
 
import javax.xml.xquery.XQConnection;
import javax.xml.xquery.XQException;
import javax.xml.xquery.XQPreparedExpression;
import javax.xml.xquery.XQSequence;
import javax.xml.xquery.XQStaticContext;
 
import oracle.xml.xquery.OXQConnection;
import oracle.xml.xquery.OXQDataSource;
import oracle.xml.xquery.OXQEntity;
import oracle.xml.xquery.OXQEntityKind;
import oracle.xml.xquery.OXQEntityLocator;
import oracle.xml.xquery.OXQEntityResolver;
import oracle.xml.xquery.OXQEntityResolverRequestOptions;
import oracle.xml.xquery.OXQView;

public class ResolveSchema {
 
    private static class MyEntityResolver extends OXQEntityResolver {
        @Override
        public OXQEntity resolveEntity(OXQEntityKind kind, OXQEntityLocator locator,
                OXQEntityResolverRequestOptions options) throws IOException {
            if (kind == OXQEntityKind.SCHEMA) {
                URI systemId = locator.getSystemIdAsURI();
                if (systemId != null && "file".equals(systemId.getScheme())) {
                    File file = new File(systemId);
                    FileInputStream input = new FileInputStream(file);
                    OXQEntity result = new OXQEntity(input);
                    result.enlistCloseable(input);
                    return result;
                }
            }
            return null;
        }
    }
  
   public static void main(String[] args) throws XQException, IOException {
        OXQDataSource ds = new OXQDataSource();
        XQConnection con = ds.getConnection();
 
        // OXQView is used to access Oracle extensions on XQJ objects.
        OXQConnection ocon = OXQView.getConnection(con);
        ocon.setEntityResolver(new MyEntityResolver());
 
        File query = new File("size.xq");
        
        // Relative URIs are resolved against the base URI before invoking the entity resolver.
        // The relative URI 'math.xq' used in the query will be resolved against this URI.
        XQStaticContext ctx = con.getStaticContext();
        ctx.setBaseURI(query.toURI().toString());
        
        FileInputStream queryInput = new FileInputStream(query);
        XQPreparedExpression expr = con.prepareExpression(queryInput, ctx);
        queryInput.close();
        
        XQSequence result = expr.executeQuery();

        // Prints "S INVALID:big XL INVALID:42"
        System.out.println(result.getSequenceAsString(null));
        
        result.close();
        expr.close();
        con.close();
    }
}

この例では、出力S INVALID:big XL INVALID:42が生成されます。

7.2.5 XQuery用にあらかじめ作成されたエンティティ・リゾルバ

XDKには、ファイル・システムおよびHTTP解決などの一般的なタスクに使用できる、OXQEntityResolverの実装がいくつか含まれています。これにより、独自のエンティティ・リゾルバを実装する必要がなくなる場合があります。

例7-14に、あらかじめ作成されたファイル・リゾルバを使用して例7-3の問合せを実行する方法を示します。

ファクトリoracle.xml.xquery.OXQFileResolverFactoryのインスタンスが接続から作成されます。次に、このファクトリを使用して、ファイル・システムに対してスキーマ、モジュールおよびドキュメントを解決するエンティティ・リゾルバを作成します。この例とは異なり、例7-4では、カスタム・エンティティ・リゾルバMyEntityResolverを使用してファイル・システムに対してドキュメントのみを解決しています。

XDKには、次のエンティティ・リゾルバ・ファクトリが用意されています。

  • oracle.xml.xquery.OXQFileResolverFactory: スキーマ、モジュールおよびドキュメントの場所の'file:' URIを解決するエンティティ・リゾルバを作成します。

  • oracle.xml.xquery.OXQHttpResolverFactory: スキーマ、モジュールおよびドキュメントの場所の'http:' URIを解決するエンティティ・リゾルバを作成します。

  • oracle.xml.xquery.OXQCompositeResolverFactory: リクエストを他のエンティティ・リゾルバに委任するエンティティ・リゾルバを作成します。どの種類のリクエストに対しても、リゾルバは委任したいずれかのリゾルバから受け取ったnull以外の最初の結果を返します。

  • oracle.xml.xquery.OXQJavaResolverFactory: Java静的メソッドまたはクラスに対して外部関数およびモジュールを解決するエンティティ・リゾルバを作成します。

関連項目:

これらのファクトリ・インタフェースのAPI情報については、Oracle Database XML Java APIリファレンスのパッケージoracle.xml.xqueryに関する項を参照してください

例7-14 あらかじめ作成されたファイル・リゾルバを使用した問合せの実行

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
 
import javax.xml.xquery.XQConnection;
import javax.xml.xquery.XQException;
import javax.xml.xquery.XQPreparedExpression;
import javax.xml.xquery.XQSequence;
import javax.xml.xquery.XQStaticContext;
 
import oracle.xml.xquery.OXQConnection;
import oracle.xml.xquery.OXQDataSource;
import oracle.xml.xquery.OXQFileResolverFactory;
import oracle.xml.xquery.OXQView;

public class ResolverFactory {
    public static void main(String[] args) throws XQException, IOException {
        OXQDataSource ds = new OXQDataSource();
        XQConnection con = ds.getConnection();
 
        // OXQView is used to access Oracle extensions on XQJ objects.
        OXQConnection ocon = OXQView.getConnection(con);
        OXQFileResolverFactory factory = ocon.createEntityResolverFactory(OXQFileResolverFactory.class);
        ocon.setEntityResolver(factory.createResolver());
 
        File query = new File("books.xq");
        
        // Relative URIs are resolved against the base URI before invoking the entity resolver.
        // The relative URI 'books.xml' used in the query will be resolved against this URI.
        XQStaticContext ctx = con.getStaticContext();
        ctx.setBaseURI(query.toURI().toString());
 
        FileInputStream queryInput = new FileInputStream(query);
        XQPreparedExpression expr = con.prepareExpression(queryInput, ctx);
        queryInput.close();
        
        XQSequence result = expr.executeQuery();

        // Prints "<title>A Game of Thrones</title>"
        System.out.println(result.getSequenceAsString(null));
        
        result.close();
        expr.close();
        con.close();
    }
}

この例では、出力<title>A Game of Thrones</title>が生成されます。

7.2.6 他のタイプのエンティティの解決

XQJエンティティ・リゾルバを使用して、ドキュメント、スキーマ、モジュールおよび外部関数に加え、他のエンティティを取得できます。

表7-1に、これらの他のエンティティを示します。

表7-1 様々なエンティティ・タイプの説明

OXQEntityKind 説明
TEXT fn:unparsed-textおよびfn:unparsed-text-linesの結果。
ENVIRONMENT_VARIABLE fn:available-environment-variablesおよびfn:environment-variableの結果。
DOCUMENT_TYPE 関数fn:docの静的タイプ。
COLLECTION fn:collectionによって返されるドキュメント。
URI_COLLECTION fn:uri-collectionによって返されるURI。
XML_PARSER_FACTORY XMLデータの解析に使用されるStAX実装。
XML_ENTITY StAXパーサーが外部XMLリソースを解決する必要がある場合に使用されます。
UPD_PUT fn:putの動作を制御します。
COLLATION 照合URIの動作を制御します。

これらのエンティティ・タイプの使用方法の詳細は、Oracle Database XML Java APIリファレンスのクラスoracle.xml.xquery.OXQEntityに関する項を参照してください。

7.3 XQuery出力宣言

XQuery 3.0では、問合せ内からシリアライズ・パラメータの値を設定するために使用できる、出力宣言が定義されます。

出力宣言は、名前空間http://www.w3.org/2010/xslt-xquery-serializationのオプション宣言です。これを問合せで使用して、静的コンテキストでシリアライズ・パラメータを宣言および設定します。

デフォルトでは、これらの静的コンテキストのシリアライズ・パラメータは無視されますが、XQJのメソッドOXQPreparedExpression#getExpressionStaticContext()およびOXQStaticContext#getSerializationParameters()を使用してこれらにアクセスできます。

例7-15に、オプション宣言の値へのアクセス方法を示します。

オプション宣言は、問合せの結果をシリアライズする場合にも使用できます。例7-16例7-15に類似していますが、問合せ結果をシリアライズするときに静的コンテキストのシリアライズ・パラメータを使用しています。

注意:

オプションoutput:parameter-documentのURI値は、エンティティ・リゾルバOXQEntityResolverおよびエンティティ種類OXQEntityKind#DOCUMENTを使用して解決されます。「他のタイプのエンティティの解決」を参照してください。

関連項目:

XQuery 3.0: An XML Query Languageシリアライズに関する項

例7-15 オプション宣言の値へのアクセス

import javax.xml.xquery.XQConnection;
import javax.xml.xquery.XQException;
import javax.xml.xquery.XQPreparedExpression;
import javax.xml.xquery.XQStaticContext;

import oracle.xml.xquery.OXQDataSource;
import oracle.xml.xquery.OXQPreparedExpression;
import oracle.xml.xquery.OXQSerializationParameters;
import oracle.xml.xquery.OXQStaticContext;
import oracle.xml.xquery.OXQView;

public class OptionDeclarations1 {
    
    public static void main(String[] args) throws XQException {
        OXQDataSource ds = new OXQDataSource();
        XQConnection con = ds.getConnection();
        String query = 
            "declare option output:indent 'yes'; \n" +
            "declare option output:encoding 'UTF-16'; \n" + 
            "<person><first>John</first><last>Doe</last></person>";
        
        XQPreparedExpression expr = con.prepareExpression(query); 

        OXQPreparedExpression oexpr = OXQView.getPreparedExpression(expr);
        XQStaticContext ctx = oexpr.getExpressionStaticContext();
        OXQStaticContext octx = OXQView.getStaticContext(ctx);
        OXQSerializationParameters params = octx.getSerializationParameters();
        
        System.out.println("indent=" + params.isIndent());
        System.out.println("encoding=" + params.getEncoding());
        
        expr.close();
        con.close();
    }
}

これによって、次の出力が生成されます。

  indent=true
  encoding=UTF-16

例7-16 問合せ結果をシリアライズする際のオプション宣言の使用

package oracle.xml.xquery.examples.published;

import javax.xml.xquery.XQConnection;
import javax.xml.xquery.XQException;
import javax.xml.xquery.XQPreparedExpression;
import javax.xml.xquery.XQResultSequence;
import javax.xml.xquery.XQStaticContext;

import oracle.xml.xquery.OXQDataSource;
import oracle.xml.xquery.OXQPreparedExpression;
import oracle.xml.xquery.OXQSerializationParameters;
import oracle.xml.xquery.OXQStaticContext;
import oracle.xml.xquery.OXQView;

public class OptionDeclarations2 {

    public static void main(String[] args) throws XQException {
        OXQDataSource ds = new OXQDataSource();
        XQConnection con = ds.getConnection();
        String query = 
            "declare option output:indent 'yes'; \n" +
            "declare option output:omit-xml-declaration 'no'; \n" + 
            "<person><first>John</first><last>Doe</last></person>";
        
        XQPreparedExpression expr = con.prepareExpression(query); 

        OXQPreparedExpression oexpr = OXQView.getPreparedExpression(expr);
        XQStaticContext ctx = oexpr.getExpressionStaticContext();
        OXQStaticContext octx = OXQView.getStaticContext(ctx);
        OXQSerializationParameters params = octx.getSerializationParameters();
        
        XQResultSequence result = expr.executeQuery();
        result.writeSequence(System.out, params.createProperties());
        result.close();
        
        expr.close();
        con.close();
    }
}

これによって、次の出力が生成されます。

<?xml version="1.0" encoding="UTF-8"?>
<person>
    <first>John</first>
    <last>Doe</last>
</person>

7.4 XQueryによるアプリケーションのパフォーマンスおよびスケーラビリティの改善

XDK XQueryプロセッサには、アプリケーションのパフォーマンスとスケーラビリティを向上させるための機能がいくつか用意されています。

トピック:

7.4.1 ストリーミング問合せ評価

XDK XQuery Processor for Javaでは、多くのタイプの問合せのストリーミング評価をサポートしています。入力XMLが非常に大きい場合でも、ストリーミング評価では少量のメイン・メモリーしか必要ありません。

ストリーミング評価を簡略化するために、次のアクションが推奨されます。

  • 静的コンテキストでバインディング・モードを遅延モードに設定します(Oracle Database XML Java APIリファレンスのメソッドjavax.xml.xquery.XQStaticContext.setBindingMode(int)メソッドに関する項を参照)。バインディング・モードが遅延でない場合、バインドされる際に入力XMLは完全にマテリアライズされます。

  • 入力XMLをjava.io.InputStreamjava.io.Readerまたはjavax.xml.stream.XMLStreamReaderのインスタンスとして提供します。入力XMLは、式にバインドするかエンティティ・リゾルバから返すことによって、問合せプロバイダに提供されます。

  • 次のように、javax.xml.xquery.XQSequenceインスタンスが、マテリアライズが不要な方法で使用されるようにします。

    • 文字列シリアライズ・メソッドgetSequenceAsString(...)およびgetItemAsString(...)では、データはメモリーに保持される文字列として生成されます。かわりに、writeSequence(...)またはwriteItem(...)メソッドを使用して、シーケンスをシリアライズしてください。

    • getNode()メソッドでは、メモリーに保持されるDocument Object Model (DOM)ノードが構築されます。かわりに、getSequenceAsStream()またはgetItemAsStream()メソッドを使用してStreaming API for XML (StAX)ストリームを取得することを検討してください。

    • getItem()メソッドでは、メモリー内で現在のアイテムがコピーされてマテリアライズされます。かわりに、java.xml.xquery.XQSequenceインスタンスで直接メソッドを使用して、現在のアイテムにアクセスしてください(Oracle Database XML Java APIリファレンスのインタフェースjavax.xml.xquery.XQItemAccessorに関する項を参照)。

この項に示すコードでは、ストリーミング評価が妨げられない方法で、XQJを使用して問合せを起動します。

例7-17に、books2.xqの内容を示します。

例7-18では、ストリーミング評価を有効にする問合せを設定します。この例では、ファイルresults.xmlに出力<title>A Game of Thrones</title>が書き込まれます。

準備された式にバインドする際、books.xmlがマテリアライズされないように、バインディング・モードが値BINDING_MODE_DEFERREDに設定されます。同様に、結果は出力ストリームに書き込まれ、マテリアライズされません。

例を簡略化するために、入力ファイルはbooks.xmlは小さくなっています。ファイルに何百万もの書籍が含まれる場合でも、メモリーには一度に1つの書籍要素しか保持されないため、問合せの評価では小さな最大ヒープ・サイズしか必要ありません。例7-3の問合せbooks.xqとは異なり、問合せbooks2.xqではエンティティ・リゾルバを定義する必要はありません。例(books.xqbooks2.xq)は両方ともストリーム可能です。

例7-17 books2.xq

declare variable $doc external;
 
for $book in $doc/books/book
where xs:decimal($book/price) gt 10.00
return
  $book/title

例7-18 ストリーミング評価の促進

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
 
import javax.xml.namespace.QName;
import javax.xml.xquery.XQConnection;
import javax.xml.xquery.XQConstants;
import javax.xml.xquery.XQException;
import javax.xml.xquery.XQPreparedExpression;
import javax.xml.xquery.XQSequence;
import javax.xml.xquery.XQStaticContext;
 
import oracle.xml.xquery.OXQDataSource;
 
public class Streaming {
 
    public static void main(String[] args) throws XQException, IOException {
        OXQDataSource ds = new OXQDataSource();
        XQConnection con = ds.getConnection();
        
        XQStaticContext ctx = con.getStaticContext();
        ctx.setBindingMode(XQConstants.BINDING_MODE_DEFERRED);
        con.setStaticContext(ctx);
        
        FileInputStream input = new FileInputStream("books.xml");
        FileInputStream query = new FileInputStream("books2.xq");
        FileOutputStream output = new FileOutputStream("result.xml");
        
        XQPreparedExpression expr = con.prepareExpression(query);
        query.close();
        expr.bindDocument(new QName("doc"), input, null, null);
        
        XQSequence result = expr.executeQuery();

        // Writes "<title>A Game of Thrones</title>" to file results.xml
        result.writeSequence(output, null);
        
        result.close();
        input.close();
        output.close();
        expr.close();
        con.close();
    }
}

7.4.2 外部ストレージ

問合せによっては、プロセッサは問合せ評価中に入力XMLの一部をメイン・メモリーに格納しなければならないことがあります。

このシナリオは、たとえば次のような場合に発生します。

  • シーケンスがソートされる場合。

  • 変数にバインドされた値を、複数回使用する場合。

  • パス式が逆行軸ステップを使用する場合。

このような場合にメモリー使用量を削減するために、メイン・メモリーではなく外部ストレージを使用してXMLをマテリアライズするように、XQueryプロセッサを構成できます。外部ストレージを使用可能にするには、データ・ソース・プロパティOXQConstants.USE_EXTERNAL_STORAGEtrueに設定し、動的コンテンツでoracle.xml.scalable.PageManagerインスタンスを設定します。

注意:

外部ストレージを使用すると、問合せ処理中に消費されるメイン・メモリーの容量を大幅に削減できます。ただし、パフォーマンスも低下する可能性があります。

例7-19に、XMLをマテリアライズする際に、XQueryプロセッサでメイン・メモリーではなくディスクベースのストレージを使用できるようにする方法を示します。この例では、ファイルresults.xmlに出力<title>A Game of Thrones</title>が書き込まれます。

例7-19 外部ストレージを使用するようにXQuery Processorを構成

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
 
import javax.xml.namespace.QName;
import javax.xml.xquery.XQConnection;
import javax.xml.xquery.XQConstants;
import javax.xml.xquery.XQException;
import javax.xml.xquery.XQPreparedExpression;
import javax.xml.xquery.XQSequence;
import javax.xml.xquery.XQStaticContext;
 
import oracle.xml.scalable.FilePageManager;
import oracle.xml.xquery.OXQDataSource;
import oracle.xml.xquery.OXQPreparedExpression;
import oracle.xml.xquery.OXQView;

public class ExternalStorage {
 
    public static void main(String[] args) throws XQException, IOException {
        OXQDataSource ds = new OXQDataSource();
        ds.setProperty(OXQDataSource.USE_EXTERNAL_STORAGE, "true");
        
        XQConnection con = ds.getConnection();
        XQStaticContext ctx = con.getStaticContext();
        ctx.setBindingMode(XQConstants.BINDING_MODE_DEFERRED);
        con.setStaticContext(ctx);
        
        FileInputStream input = new FileInputStream("books.xml");
        FileInputStream query = new FileInputStream("books2.xq");
        FileOutputStream output = new FileOutputStream("results.xml");
        
        XQPreparedExpression expr = con.prepareExpression(query);
        query.close();
        expr.bindDocument(new QName("doc"), input, null, null);
        
        // Set a page manager that will be used by the XQuery processor if XML needs to be materialized
        OXQPreparedExpression oexpr = OXQView.getPreparedExpression(expr);
        File temporaryFile = File.createTempFile("books", ".pagefile");
        temporaryFile.deleteOnExit();
        oexpr.setPageManager(new FilePageManager(temporaryFile.getAbsolutePath()));
        
        XQSequence result = expr.executeQuery();

        // Writes to file results.xml: "<title>A Game of Thrones</title>"
        result.writeSequence(output, null);
        
        result.close();
        input.close();
        output.close();
        expr.close();
        con.close();
    }
}

7.4.3 XQJのスレッド・セーフティ

OracleによるXQJの実装は、スレッドセーフではありません。たとえば、javax.xml.xquery.XQSequenceのインスタンスには、1つのスレッドのみがアクセスする必要があります。ただし、javax.xml.xquery.XQConnectionのインスタンスを管理するために、制限された形式でのスレッド・セーフティがサポートされます。

  • XQConnectionのインスタンスは、XQExpressionXQPreparedExpressionXQItem, XQSequenceXQItemTypeおよびXQSequenceTypeの各インスタンスの作成においてファクトリとして機能します。1つのスレッドが、他のスレッドで使用されるこれらのオブジェクトの作成を管理できます。たとえば、同じ接続によって1つのスレッドで作成されたXQPreparedExpressionインスタンスを、別のスレッドで使用できます。ただし、各XQPreparedExpressionインスタンスは、1つのスレッドによってのみ実行する必要があります。同じ接続の式が同時に評価される際、指定されたoracle.xml.xquery.OXQEntityResolverの任意のユーザー定義実装はスレッドセーフである必要があります。

  • メソッドXQConnection.close()は、接続から取得されたすべてのXQExpressionおよびXQPreparedExpressionインスタンスをクローズします。これらのインスタンスをクローズすると、式から取得されたすべてのXQResultSequenceおよびXQResultItemインスタンスがクローズされます。接続から取得された式が他のスレッドで処理されている間、メソッドXQConnection.close()をコールできます。この場合、式によって保持されている登録済のすべてのリソース(java.io.InputStreamjava.io.Readerなど)がクローズされます。この規定では、登録済のすべてのリソースが、スレッドセーフなクローズ・メソッドをサポートしていると想定しています。たとえば、java.io.Closeableの多くのJDK実装は、この要件を満たしています。ただし、javax.xml.stream.XMLStreamReaderの多くの実装には、スレッドセーフなクローズ・メソッドはありません。これがサポートされていない実装を、2番目のスレッドがまだ読取りを実行中にクローズすると、予期しない結果が生じる可能性があります(Oracle Database XML Java APIリファレンスのインタフェースoracle.xml.xquery.OXQCloseableに関する項を参照)。

    関連項目:

    Oracle Database XML Java APIリファレンスのメソッドoracle.xml.xquery.OXQConnection.copyExpression(XQPreparedExpression)関する項

7.5 更新の実行

XDKでは、問合せの更新を実行する機能によってXQJが拡張されています。XML文書をjavax.xml.xquery.XQItemのインスタンスとして読み取った後、拡張機能XQuery Update Facilityを使用して変更できます。

この機能はデフォルトで無効です。これは、動的コンテキストで更新モードをoracle.xml.xquery.OXQConstants.UPDATE_MODE_ENABLEDに設定することで、有効にできます。

更新する文書は、遅延モードでバインドされている必要があります(Oracle Database XML Java APIリファレンスのメソッドjavax.xml.xquery.XQStaticContext.setBindingMode(int)に関する項を参照)。バインディング・モードが遅延に設定されていない場合、問合せ実行の前に、入力バインディングがコピーされます。このため、コピーのみが更新されます。

この項の各例では、XQuery Update Facilityを使用してXML文書を変更する方法を示します。

例7-20に、configuration.xmlの内容を示します。

例7-21に、update.xqの内容を示します。

例7-22に、更新後のconfiguration.xmの内容を示します。

例7-23に、問合せupdate.xqの実行方法を示します。

例では、次のアクションが行われます。

  1. XMLファイルconfiguration.xmljavax.xml.xquery.XQItemのインスタンスとして読み取られます。

  2. アイテムが問合せupdate.xqの準備された式にバインドされます。

  3. 問合せupdate.xqが実行されます。

  4. 変更された文書がファイルconfiguration.xmlに書き込まれます。

関連項目:

例7-20 configuration.xml

<configuration>
  <property>
    <name>hostname</name>
    <value>example.com</value>
  </property>
  <property>
    <name>timeout</name>
    <value>1000</value>
  </property>
</configuration>

例7-21 update.xq

declare variable $doc external;
 
let $timeout := $doc/configuration/property[name eq "timeout"]
return
  replace value of node $timeout/value 
  with 2 * xs:integer($timeout/value)

例7-22 更新されたファイルconfiguration.xml

<configuration>
  <property>
    <name>hostname</name>
    <value>example.com</value>
  </property>
  <property>
    <name>timeout</name>
    <value>2000</value>
  </property>
</configuration>

例7-23 問合せupdate.xqの更新の実行

import java.io.FileInputStream;
import java.io.IOException;
import java.io.FileOutputStream;
 
import javax.xml.namespace.QName;
import javax.xml.xquery.XQConnection;
import javax.xml.xquery.XQConstants;
import javax.xml.xquery.XQException;
import javax.xml.xquery.XQItem;
import javax.xml.xquery.XQPreparedExpression;
import javax.xml.xquery.XQStaticContext;
 
import oracle.xml.xquery.OXQConstants;
import oracle.xml.xquery.OXQDataSource;
import oracle.xml.xquery.OXQView;
 
public class UpdateDocument {
    public static void main(String[] args) throws XQException, IOException {
        OXQDataSource ds = new OXQDataSource();
        XQConnection con = ds.getConnection();
        
        XQStaticContext ctx = con.getStaticContext();
        // Set the binding mode to deferred so the document
        // item is not copied when it is bound.
        ctx.setBindingMode(XQConstants.BINDING_MODE_DEFERRED);
        con.setStaticContext(ctx);
 
        FileInputStream input = new FileInputStream("configuration.xml");
        XQItem doc = con.createItemFromDocument(input, null, null);
        input.close();
        
        System.out.println("Before update: \n" + doc.getItemAsString(null));
        
        FileInputStream query = new FileInputStream("update.xq");
        XQPreparedExpression expr = con.prepareExpression(query);
        query.close();
        expr.bindItem(new QName("doc"), doc);
        // Enable updates (disabled by default)
        OXQView.getDynamicContext(expr).setUpdateMode(OXQConstants.UPDATE_MODE_ENABLED);
        expr.executeQuery();
 
        System.out.println("After update: \n" + doc.getItemAsString(null));
        
        // Write the modified document back to the file
        FileOutputStream out = new FileOutputStream("configuration.xml");
        doc.writeItem(out, null);

        expr.close();
        con.close();
    }
}

7.6 Oracle XQueryの関数および演算子

Oracleでは、標準のXQuery関数および演算子に加え、いくつかのOracle固有の関数をサポートしています。

Oracle固有のXQuery関数では、名前空間http://xmlns.oracle.com/xdk/xquery/functionが使用されます。名前空間の接頭辞 ora-fnはあらかじめ宣言されており、モジュールは自動的にインポートされます。

トピック:

7.6.1 期間、日付および時間用のOracle XQuery関数

Oracle XQuery関数を使用して、XQueryで期間、日付および時間を操作できます。

Oracle XQuery関数は、名前空間http://xmlns.oracle.com/xdk/xquery/functionにあります。名前空間の接頭辞ora-fnはあらかじめ宣言されており、モジュールは自動的にインポートされます。

トピック:

7.6.1.1 ora-fn:date-from-string-with-format

このOracle XQuery関数は、指定されたパターンに従って文字列から新しい日付値を返します。

シグネチャ

ora-fn:date-from-string-with-format($format as xs:string?,
                                    $dateString as xs:string?, 
                                    $locale as xs:string*)
                                   as xs:date?

ora-fn:date-from-string-with-format($format as xs:string?,
                                    $dateString as xs:string?)
                                   as xs:date?

パラメータ

$format: パターン、「format引数」を参照してください

$dateString: 日付を表す入力文字列

$locale: ロケールを表す1つから3つまでのフィールド値、「locale引数」を参照してください

この例では、現在のタイムゾーンでの指定された日付が返されます。

ora-fn:date-from-string-with-format("yyyy-MM-dd G", "2013-06-22 AD")
7.6.1.2 ora-fn:date-to-string-with-format

このOracle XQuery関数は、指定されたパターンで日付文字列を返します。

シグネチャ

ora-fn:date-to-string-with-format($format as xs:string?,
                                  $date as xs:date?,
                                  *$locale as xs:string?)
                                 as xs:string?

ora-fn:date-to-string-with-format($format as xs:string?,
                                  $date as xs:date?)
                                 as xs:string?

パラメータ

$format: パターン、「format引数」を参照してください

$date: 日付

$locale: ロケールを表す1つから3つまでのフィールド値、「locale引数」を参照してください

この例では、文字列2013-07-15が返されます。

ora-fn:date-to-string-with-format("yyyy-mm-dd", xs:date("2013-07-15"))
7.6.1.3 ora-fn:dateTime-from-string-with-format

このOracle XQuery関数は、指定されたパターンに従って入力文字列から新しい日時値を返します。

シグネチャ

ora-fn:dateTime-from-string-with-format($format as xs:string?, 
                                        $dateTimeString as xs:string?,
                                        $locale as xs:string?)
                                       as xs:dateTime?

ora-fn:dateTime-from-string-with-format($format as xs:string?,
                                        $dateTimeString as xs:string?)
                                       as xs:dateTime?

パラメータ

$format: パターン、「format引数」を参照してください

$dateTimeString: 日付および時間

$locale: ロケールを表す1つから3つまでのフィールド値、「locale引数」を参照してください

この例では、現在のタイムゾーンでの指定された日付と11:04:00AMが返されます。

ora-fn:dateTime-from-string-with-format("yyyy-MM-dd 'at' hh:mm", 
                                        "2013-06-22 at 11:04")

次の例では、現在のタイムゾーンでの指定された日付と12:00:00AMが返されます。

ora-fn:dateTime-from-string-with-format("yyyy-MM-dd G",
                                        "2013-06-22 AD") 
7.6.1.4 ora-fn:dateTime-to-string-with-format

このOracle XQuery関数は、指定されたパターンで日付および時間文字列を返します。

シグネチャ

ora-fn:dateTime-to-string-with-format($format as xs:string?,
                                      $dateTime as xs:dateTime?,
                                      $locale as xs:string?)
                                     as xs:string?

ora-fn:dateTime-to-string-with-format($format as xs:string?,
                                      $dateTime as xs:dateTime?)
                                     as xs:string?

パラメータ

$format: パターン、「format引数」を参照してください

$dateTime: 日付および時間

$locale: ロケールを表す1つから3つまでのフィールド値、「locale引数」を参照してください

この例では、文字列07 JAN 2013 10:09 PM ADが返されます。

ora-fn:dateTime-to-string-with-format("dd MMM yyyy hh:mm a G",
                                      xs:dateTime("2013-01-07T22:09:44"))

次の例では、文字列"01-07-2013"が返されます。

ora-fn:dateTime-to-string-with-format("MM-dd-yyyy",
                                      xs:dateTime("2013-01-07T22:09:44")) 
7.6.1.5 ora-fn:time-from-string-with-format

このOracle XQuery関数は、指定されたパターンに従って入力文字列から新しい時間値を返します。

シグネチャ

ora-fn:time-from-string-with-format($format as xs:string?,
                                    $timeString as xs:string?,
                                    $locale as xs:string?)
                                   as xs:time?

ora-fn:time-from-string-with-format($format as xs:string?,
                                    $timeString as xs:string?)
                                   as xs:time?

パラメータ

$format: パターン、「format引数」を参照してください

$timeString: 時間

$locale: ロケールを表す1つから3つまでのフィールド値、「locale引数」を参照してください

この例では、現在のタイムゾーンでの9:45:22 PMが返されます。

ora-fn:time-from-string-with-format("HH.mm.ss", "21.45.22")

次の例では、現在のタイムゾーンでの8:07:22 PMが返されます。

fn-bea:time-from-string-with-format("hh:mm:ss a", "8:07:22 PM") 
7.6.1.6 ora-fn:time-to-string-with-format

このOracle XQuery関数は、指定されたパターンで時間文字列を返します。

シグネチャ

ora-fn:time-to-string-with-format($format as xs:string?,
                                  $time as xs:time?,
                                  $locale as xs:string?)
                                 as xs:string?

ora-fn:time-to-string-with-format($format as xs:string?, $time as xs:time?) as xs:string?

パラメータ

$format: パターン、「format引数」を参照してください

$time: 時間

$locale: ロケールを表す1つから3つまでのフィールド値、「locale引数」を参照してください

この例では、文字列"10:09 PM"が返されます。

ora-fn:time-to-string-with-format("hh:mm a", xs:time("22:09:44"))

次の例では、文字列"22:09 PM"が返されます。

ora-fn:time-to-string-with-format("HH:mm a", xs:time("22:09:44"))
7.6.1.7 format引数

$format引数は、日付値または時間値を構成する様々なフィールドを識別します。

7.6.1.8 locale引数

$localeは、地理的、政治的または文化的な特定の地域を表します。

これは最大3つのフィールドによって定義されます。

  1. 言語コード: ISO 639 alpha-2またはalpha-3言語コード、または最大8文字の登録済の言語のサブタグ。たとえば、enは英語、jaは日本語を表します。

  2. 国コード: ISO 3166 alpha-2の国コードまたはUN M.49 numeric-3の地域コード。たとえば、USは米国、029はカリブを表します。

  3. バリアント: 特定の方言など、ロケールのバリエーションを示します。複数の値を重要度の高い順に記述し、各値をアンダースコア(_)で区切ります。これらの値は英大小文字が区別されるので、このとおりに入力してください。

関連項目:

7.6.2 文字列用のOracle XQuery関数

Oracle XQuery関数を使用して、XQueryで文字列を操作できます。

Oracle XQuery関数は、名前空間http://xmlns.oracle.com/xdk/xquery/functionにあります。名前空間の接頭辞ora-fnはあらかじめ宣言されており、モジュールは自動的にインポートされます。

トピック:

7.6.2.1 ora-fn:pad-left

固定長文字列を作成するために、文字列の左側にパディング文字を追加します。入力文字列が指定された長さを超えている場合、文字列は切り捨てられ、指定された長さの部分文字列が返されます。デフォルトのパディング文字はスペース(ASCII 32)です。

シグネチャ

ora-fn:pad-left($str as xs:string?,
                $size as xs:integer?,
                $pad as xs:string?)
               as xs:string?

ora-fn:pad-left($str as xs:string?,
                $size as xs:integer?)
               as xs:string?

パラメータ

$str: 入力文字列

$size: $strにパディング文字を追加することによって取得される、任意の固定長

$pad: パディング文字

いずれかの引数が空のシーケンスである場合、この関数は空のシーケンスを返します。

この例では、最大6文字になるまで入力文字列の先頭に"01"を付加します。返される文字列は、"010abc"です。この関数は、1つの完全なパディング文字と1つの部分的なパディング文字を返します。

ora-fn:pad-left("abc", 6, "01")

次の例では、入力文字列が指定された固定長を超えているため、"ab"のみが返されます。

ora-fn:pad-left("abcd", 2, "01")

この例では、指定された最大6文字になるまで入力文字列の先頭に空白を付加します。返される文字列" abcd"は、先頭に2つの空白が付加されています。

ora-fn:pad-left("abcd", 6)

次の例では、入力文字列が指定された固定長を超えているため、"ab"のみが返されます。

ora-fn:pad-left("abcd", 2)
7.6.2.2 ora-fn:pad-right

固定長文字列を作成するために、文字列の右側にパディング文字を追加します。入力文字列が指定された長さを超えている場合、文字列は切り捨てられ、指定された長さの部分文字列が返されます。デフォルトのパディング文字はスペース(ASCII 32)です。

シグネチャ

ora-fn:pad-right($str as xs:string?,
                 $size as xs:integer?,
                 $pad as xs:string?)
                as xs:string?

ora-fn:pad-right($str as xs:string?,
                 $size as xs:integer?)
                as xs:string?

パラメータ

$str: 入力文字列

$size: $strにパディング文字を追加することによって取得される、任意の固定長

$pad: パディング文字

いずれかの引数が空のシーケンスである場合、この関数は空のシーケンスを返します。

この例では、最大6文字になるまで入力文字列に"01"を付加します。返される文字列は、"abc010"です。この関数は、1つの完全なパディング文字と1つの部分的なパディング文字を返します。

ora-fn:pad-right("abc", 6, "01")

この例では、入力文字列が指定された固定長を超えているため、"ab"のみが返されます。

ora-fn:pad-right("abcd", 2, "01")

この例では、指定された最大6文字になるまで入力文字列に空白を付加します。返される文字列"abcd "は、末尾に2つの空白が付加されています。

ora-fn:pad-right("abcd", 6)

次の例では、入力文字列が指定された固定長を超えているため、"ab"のみが返されます。

ora-fn:pad-right("abcd", 2)
7.6.2.3 ora-fn:trim

文字列の先頭または末尾の空白をすべて削除します。

シグネチャ

ora-fn:trim($input as xs:string?) as xs:string?

パラメータ

$input: 切り捨てられる文字列。$inputが空のシーケンスである場合、この関数は空のシーケンスを返します。他のデータ型では、エラーが発生します。

この例では、文字列"abc"が返されます。

ora-fn:trim("  abc  ")
7.6.2.4 ora-fn:trim-left

文字列の先頭の空白を削除します。

シグネチャ

ora-fn:trim-left($input as xs:string?) as xs:string?

パラメータ

$input: 切り捨てられる文字列。$inputが空のシーケンスである場合、この関数は空のシーケンスを返します。他のデータ型では、エラーが発生します。

この例では、先頭の空白が削除されて、文字列"abc    "が返されます。

ora-fn:trim-left("    abc    ")
7.6.2.5 ora-fn:trim-right

文字列の末尾の空白を削除します。

シグネチャ

ora-fn:trim-right($input as xs:string?) as xs:string?

パラメータ

$input: 切り捨てられる文字列。$inputが空のシーケンスである場合、この関数は空のシーケンスを返します。他のデータ型では、エラーが発生します。

この例では、末尾の空白が削除されて、文字列"    abc"が返されます。

ora-fn:trim-left("    abc    ")

7.7 XQuery Processor for Javaの標準および仕様

XQuery Processor for Javaが準拠している標準および仕様を示します。

  • XQuery 3.0: An XML Query Language

    注意:

    XQuery 1.0レベルの機能はすべてサポートされます。XQuery 3.0レベルの機能はサポートされますが、FLWORウィンドウ句、FLWORカウント句、ネームスペース・コンストラクタ、小数書式宣言、fn:format-numberfn:format-integerfn:format-datefn:format-timefn:pathおよびXQueryの高階関数は対象外です。
  • XQuery Update Facility 1.0

  • XQueryX 3.0 (XQuery 3.0のXML構文)

  • JSR-000225 XQuery API for Java

注意:

XDK XQuery processor for Javaは、Oracle XML DBのOracle XQJ実装を含め、他のXQJ実装とは相互運用できません。(相互運用可能の意味については、『JSR-225: XQuery API for Java』を参照してください。)

トピック:

7.7.1 XQueryのオプション機能

XQuery仕様では、特定の機能がオプションとして定義されています。XDKでサポートされるものを、それらを指定する標準とともに示します。

XDKでサポートされるオプションの機能は、次のとおりです。

7.7.2 実装定義の項目

XQJ仕様およびXQuery仕様では、特定分野の定義は実装によって異なり得るとしています。XDKの実装定義項目について簡単に説明します。

表7-2に、XQJの実装定義項目をまとめます。

表7-2 XQJの実装定義項目

説明 動作

XQDataSource実装のクラス名

oracle.xml.xquery.OXQDataSource

OXQDataSourceで定義されたプロパティ

なし。ユーザー名とパスワードは警告なしで無視されます。

JDBC接続のサポート

JDBC接続はサポートされません。

コマンド

サポートされません。

メソッドXQPreparedExpression.cancel()での問合せ実行の取消し

あり。

シリアライズ

あり。

追加のStAXまたはSAXイベント

なし。

ユーザー定義スキーマ型

あり。

ノードが外部変数にバインドされている場合の、ノードID、文書順、ノード・コンテキストの完全保持

保持されません。

ログイン・タイムアウト

サポートされません。

トランザクション

サポートされません。トランザクション・メソッドがコールされると、例外がスローされます。

入力ノードが文書ノードでない場合のXQItemAccessor.getNodeUri()メソッドの動作

例外。

匿名型のXQItemType.getTypeName()メソッド

一意の名前。

XQItemType.getSchemaURI()メソッド

型がXQJから作成される場合は、スキーマURIが返されます。そうでない場合はなし。

入力が整形式のXML文書でない場合のXQDataFactory.createItemFromDocument()およびbindDocument()メソッド

例外。

クラスXQQueryExceptionによって戻される追加のエラー・コード

Oracle固有のエラー・コードの修飾名は、名前空間http://xmlns.oracle.com/xdk/xquery/errorsにあります.

ConnectionPoolXQDataSourcePooledXQConnectionXQConnectionEventおよびXQConnectionEventListenerインタフェース

なし。

XQDataSource.getConnection(java.sql.Connection)

JDBC接続はサポートされません。このメソッドがコールされると、例外がスローされます。

XQDataSource.getConnection(java.lang.String, java.lang.String)

getConnection()と同じです。パラメータは無視されます。

注意:

表7-2の機能のXDKサポートは、Oracle XML DBサポートとは異なります。

表7-3に、XQueryの実装定義項目をまとめます。

表7-3 XQueryの実装定義項目

項目 動作

式の構成に使用されるUnicodeのバージョン

使用するJavaのバージョンによって異なります。Javaのバージョンが異なると、サポートされるUnicodeのバージョンも異なります。

静的に認識されている照合

Unicodeコード・ポイント照合およびクラスjava.text.Collatorまたはoracle.i18n.text.OraCollatorから導出された照合

暗黙的なタイム・ゾーン。

メソッドjava.util.Calendar.getInstance()で決定されたデフォルトのタイム・ゾーンを使用

警告が表示される状況および警告が処理される方法

なし。

エラーが外部処理環境にレポートされるメソッド

例外javax.xml.xquery.XQException

実装がXML 1.0およびXML Namesのルール、またはXML 1.1およびXML Names 1.1のルールのどちらに基づいているか

1.0.

実装によって上書きまたは拡張された、静的コンテキストまたは動的コンテキストのすべてのコンポーネント

表7-5を参照してください。

全軸機能がサポートされていない場合に、実装でサポートされるオプションの軸

完全にサポートされます。

ORDER BY句(empty leastまたはempty greatest)で順序付けキー(sortspec)によって戻された空のシーケンスのデフォルト処理

least

実装によって認識された任意の拡張式(pragmas)の名前およびセマンティック

なし。

実装によって認識された任意のオプション宣言の名前およびセマンティック

なし。

パラメータを外部関数に渡し、関数の結果を起動中の問合せに戻すプロトコル(ある場合)

XQJによって定義されます。

モジュール機能がサポートされる場合、モジュール・インポートでインポートする特定モジュールを識別するプロセス(処理する場所のヒントがある場合はそれも含む)

エンティティ・リゾルバ。「XQJエンティティの解決」を参照してください。

静的型指定機能がサポートされる場合、実装でサポートされる静的型指定拡張機能

静的モード(サブタイプに基づく)およびオプティミスティック・モード(型交差に基づく)。オプティミスティック・モードがデフォルトです。

シリアライズ機能がサポートされる場合、シリアライズを起動する方法。

XQJによって定義されます。

シリアライズ機能がサポートされる場合、byte-order-markencodingmedia-typenormalization-formomit-xml-declarationstandaloneおよびversionパラメータのデフォルト値

Oracle Database XML Java APIリファレンスのインタフェースoracle.xml.xquery.OXQSerializationParametersに関する項を参照してください。

様々なデータ型の値範囲を制限します。

小数値および整数値は任意精度を持ちます。

実装または実装定義APIによって提供される関数のシグネチャ(XQuery標準の第2.1.1項「Static Context」を参照)。

「Oracle XQueryの関数および演算子」を参照してください。

実装で提供される環境変数。

エンティティ・リゾルバ。「XQJエンティティの解決」を参照してください。

静的型指定に使用される規則(XQuery標準の第2.2.3.1項「Static Analysis Phase」を参照)。

デフォルトではオプティミスティックで、ペシミスティックに構成可能です。

実装によって提供されるシリアライズ・パラメータ(XQuery標準の第2.2.4項「Serialization」を参照)。

OXQSerializationParametersを参照してください。Oracle Database XML Java APIリファレンスを参照してください。

シリアライズ・パラメータ・ドキュメントのロケーション・ヒントが対応するXDMインスタンスを識別する方法(XQuery標準の第2.2.4項「Serialization」を参照)。

エンティティ・リゾルバ、OXQEntityKind.DOCUMENT「XQJエンティティの解決」を参照してください。

外部関数の実装が宣言された結果タイプを返さない場合に返されるエラーの種類(発生した場合)(XQuery標準の第2.2.5項「Consistency Constraints」を参照)。

 XPTY0004

実装によって定義された注釈、およびそれらに関連付けられた動作(XQuery標準の第4.15項「Annotations」を参照)。

%ora-fn:context-itemを使用すると、関数コール元のコンテキスト・アイテムを最初の引数として暗黙的に関数に渡すことができます。

たとえば、この問合せはefgとして評価されます。

 declare %ora-fn:context-item
 function local:foo($arg as node()) {
     node-name($arg)
  };

(<e/>, <f/>)/local:foo(), local:foo(<g/>)

実装によって定義された関数アサーション。

なし。

実装によって認識される関数アサーションの効果(第2.5.6.3項「The judgment subtype-assertions (AnnotationsA, AnnotationsB)」)。

該当なし。

実装によって定義される実装定義変数(XQuery標準の第3.1.2項「Variable References」を参照)。

なし。

実装でfn:unorderedに関連付けられた順序付け(XQuery標準の第3.11項「Ordered and Unordered Expressions」を参照)。

入力シーケンスの順序は変更されません。

変数err:additionalによって提供される、try/catchの追加情報(XQuery標準の第3.15項「Try/Catch Expressions」を参照)。

なし。

デフォルト境界スペース・ポリシー(XQuery標準の第4.3項「Boundary-space Declaration」を参照)。

strip

デフォルト照合(XQuery標準の第4.4項「Default Collation Declaration」を参照)。

Unicode。

デフォルト・ベースURI (XQuery標準の第4.5項「Base URI Declaration」を参照)。

なし。

表7-4に、XQuery Update Facilityの実装定義項目をまとめます。

表7-4 XQuery Update Facilityの実装定義項目

項目 動作

この実装でサポートされる再検証モード。

skip

この実装のデフォルトの再検証モード。

skip

外部関数がXDMインスタンスまたは保留中の更新リスト、あるいはその両方を、起動中の問合せに戻すメカニズム(ある場合)。

外部関数から保留中の更新リストを戻すことは、サポートされていません。

この関数がオペランドとして受け入れるノードの種類を含む、fn:put()のセマンティック。

すべてのノード・タイプが受け入れられます。ノードのストレージは、エンティティ・リゾルバによって決定されます。エンティティ種類UPD_PUTのドキュメントについては、Oracle Database XML Java APIリファレンスのクラスoracle.xml.xquery.OXQEntityに関する項を参照してください。

表7-5に、静的コンテキストのデフォルトの初期値をまとめます。

表7-5 静的コンテキストのデフォルトの初期値

コンテキスト・コンポーネント デフォルト値

静的に認識されている名前空間

err=http://w3.org/2005/xqt-errors

fn=http://www.w3.org/2005/xpath-functions

local=http://www.w3.org/2005/xquery-local-functions

math=http://www.w3.org/2005/xpath-functions/math

ora-ext=http://xmlns.oracle.com/xdk/xquery/extension

ora-java=http://xmlns.oracle.com/xdk/xquery/java

ora-xml=http://xmlns.oracle.com/xdk/xquery/xml

ora-fn=http://xmlns.oracle.com/xdk/xquery/function

output=http://www.w3.org/2010/xslt-xquery-serialization

xml=http://www.w3.org/XML/1998/namespace

xs=http://www.w3.org/2001/XMLSchema

xsi=http://www.w3.org/2001/XMLSchema-instance

ora-で始まる接頭辞は、Oracleでの使用が予約されています。今後のリリースで、ora-で始まる追加の接頭辞が、デフォルトの静的に認識されている名前空間に追加される可能性があります。

デフォルトの要素/タイプ名前空間

名前空間なし。

デフォルトの関数名前空間

fn

有効範囲内のスキーマ型

xsのビルトイン・タイプ

有効範囲内の要素宣言

なし。

有効範囲内の属性宣言

なし。

有効範囲内の変数

なし。

コンテキスト項目の静的タイプ

item()

関数シグネチャ

名前空間fnの関数およびビルトイン・アトミック・タイプのコンストラクタ。

静的に認識されている照合

Unicodeコード・ポイント照合およびクラスjava.text.Collatorまたはoracle.i18n.text.OraCollatorから導出された照合。

デフォルトの照合

Unicodeコード・ポイント照合:

http://www.w3.org/2005/xpath-functions/collation/codepoint

構成モード

preserve

順序付けモード

ordered

空のシーケンスのデフォルトの順序

least

境界スペース・ポリシー

strip

コピー名前空間モード

preserveno-inherit

ベースURI

標準で定義されたとおりです。

静的に認識されている文書

なし。

静的に認識されているコレクション

なし。

静的に認識されているデフォルトのコレクション・タイプ

node()*

シリアライズ・パラメータ

OXQSerializationParametersのデフォルトと同じです。Oracle Database XML Java APIリファレンスを参照してください。