XQuery-クイックガイド

XQueryとは

XQueryは、XML形式で保存された情報を取得するために使用される関数型言語です。XQueryは、XMLドキュメント、XML形式のデータを含むリレーショナルデータベース、またはXMLデータベースで使用できます。XQuery 3.0は、2014年4月8日からのW3C推奨です。

公式ドキュメントに記載されているXQueryの定義は次のとおりです。

XQueryは、ドキュメント、データベース、Webページ、その他ほとんどすべてを組み合わせるための標準化された言語です。それは非常に広く実装されています。それは強力で習得が容易です。XQueryは、プロプライエタリミドルウェア言語とWebアプリケーション開発言語に取って代わります。XQueryは、複雑なJavaまたはC ++プログラムを数行のコードに置き換えています。XQueryは、他の多くの方法よりも操作が簡単で、保守も簡単です。

特徴

  • Functional Language − XQueryは、XMLベースのデータを取得/クエリするための言語です。

  • Analogous to SQL − XQueryはXMLに対して、SQLはデータベースに対してです。

  • XPath based − XQueryは、XPath式を使用してXMLドキュメントをナビゲートします。

  • Universally accepted − XQueryは、すべての主要なデータベースでサポートされています。

  • W3C Standard −XQueryはW3C標準です。

XQueryの利点

  • XQueryを使用すると、階層データと表形式データの両方を取得できます。

  • XQueryは、ツリーおよびグラフィック構造のクエリに使用できます。

  • XQueryは、Webページのクエリに直接使用できます。

  • XQueryを直接使用してWebページを構築できます。

  • XQueryを使用してxmlドキュメントを変換できます。

  • XQueryは、XMLベースのデータベースおよびオブジェクトベースのデータベースに最適です。オブジェクトデータベースは、純粋な表形式のデータベースよりもはるかに柔軟で強力です。

この章では、ローカル開発環境でXQueryライブラリを設定する方法について詳しく説明します。

広く使用されているオープンソースのスタンドアロンXQueryプロセッサSaxonHome Edition(Saxon-HE)を使用しています。このプロセッサは、XSLT 2.0、XQuery 3.0、およびXPath 3.0をサポートし、パフォーマンスが高度に最適化されています。Saxon XQueryプロセッサは、XMLデータベースがなくても使用できます。例では、データベースとして単純なXMLドキュメントを使用します。

Saxon XQueryプロセッサを使用するには、アプリケーションのクラスパスにsaxon9he.jar、saxon9-test.jar、saxon9-unpack、saxon9-xqj.jarが含まれている必要があります。これらのjarファイルはダウンロードファイルで入手できます。SaxonHE9-6-0-1J.zipSaxonHE9-6-0-1J.zipをダウンロードします。

JavaベースのSaxonXQueryプロセッサを使用して、books.xqyをテストします。これは、サンプルXMLドキュメント(books.xml)に対してXQuery式を含むファイルです。

この例では、クエリを作成して処理し、価格が30を超える本のタイトル要素を取得する方法を示します。

books.xml

<?xml version="1.0" encoding="UTF-8"?>
<books>
   
   <book category="JAVA">
      <title lang="en">Learn Java in 24 Hours</title>
      <author>Robert</author>
      <year>2005</year>
      <price>30.00</price>
   </book>
   
   <book category="DOTNET">
      <title lang="en">Learn .Net in 24 hours</title>
      <author>Peter</author>
      <year>2011</year>
      <price>40.50</price>
   </book>
   
   <book category="XML">
      <title lang="en">Learn XQuery in 24 hours</title>
      <author>Robert</author>
      <author>Peter</author> 
      <year>2013</year>
      <price>50.00</price>
   </book>
   
   <book category="XML">
      <title lang="en">Learn XPath in 24 hours</title>
      <author>Jay Ban</author>
      <year>2010</year>
      <price>16.50</price>
   </book>
   
</books>

books.xqy

for $x in doc("books.xml")/books/book
where $x/price>30
return $x/title

XQueryTester.java

package com.tutorialspoint.xquery;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

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

import com.saxonica.xqj.SaxonXQDataSource;

public class XQueryTester {
   public static void main(String[] args){
      try {
         execute();
      }
      
      catch (FileNotFoundException e) {
         e.printStackTrace();
      }
      
      catch (XQException e) {
         e.printStackTrace();
      }
   }

   private static void execute() throws FileNotFoundException, XQException{
      InputStream inputStream = new FileInputStream(new File("books.xqy"));
      XQDataSource ds = new SaxonXQDataSource();
      XQConnection conn = ds.getConnection();
      XQPreparedExpression exp = conn.prepareExpression(inputStream);
      XQResultSequence result = exp.executeQuery();
      
      while (result.next()) {
         System.out.println(result.getItemAsString(null));
      }
   }	
}

XMLに対してXQueryを実行する手順

  • Step 1 −XQueryTester.javaを任意の場所にコピーします。 E: >> java

  • Step 2 −books.xmlを同じ場所にコピーします。 E: >> java

  • Step 3 −books.xqyを同じ場所にコピーします。 E: >> java

  • Step 4−コンソールを使用してXQueryTester.javaをコンパイルします。マシンにJDK1.5以降がインストールされており、クラスパスが構成されていることを確認してください。JAVAの使用方法の詳細については、JAVAチュートリアルを参照してください。

E:\java\javac XQueryTester.java
  • Step 5 −XQueryTesterを実行します

E:\java\java XQueryTester

出力

次の結果が得られます-

<title lang="en">Learn .Net in 24 hours</title>
<title lang="en">Learn XQuery in 24 hours</title>

例を理解する

  • books.xmlはサンプルデータを表します。

  • books.xqyは、books.xmlで実行されるXQuery式を表します。この表現については、次の章で詳しく説明します。

  • JavaベースのXQueryエグゼキュータプログラムであるXQueryTesterは、books.xqyを読み取り、それをXQuery式プロセッサに渡して、式を実行します。次に、結果が印刷されます。

以下は、さまざまな本の書店のレコードを含むサンプルXMLドキュメントです。

books.xml

<?xml version="1.0" encoding="UTF-8"?>
<books>
   
   <book category="JAVA">
      <title lang="en">Learn Java in 24 Hours</title>
      <author>Robert</author>
      <year>2005</year>
      <price>30.00</price>
   </book>
   
   <book category="DOTNET">
      <title lang="en">Learn .Net in 24 hours</title>
      <author>Peter</author>
      <year>2011</year>
      <price>70.50</price>
   </book>
   
   <book category="XML">
      <title lang="en">Learn XQuery in 24 hours</title>
      <author>Robert</author>
      <author>Peter</author> 
      <year>2013</year>
      <price>50.00</price>
   </book>
   
   <book category="XML">
      <title lang="en">Learn XPath in 24 hours</title>
      <author>Jay Ban</author>
      <year>2010</year>
      <price>16.50</price>
   </book>
   
</books>

以下は、上記のXMLドキュメントで実行されるクエリ式を含むサンプルXqueryドキュメントです。目的は、価格が30を超えるXMLノードのタイトル要素を取得することです。

books.xqy

for $x in doc("books.xml")/books/book
where $x/price>30
return $x/title

結果

<title lang="en">Learn .Net in 24 hours</title>
<title lang="en">Learn XQuery in 24 hours</title>

結果の確認

結果を確認するには、books.xqy(環境設定の章に記載)の内容を上記のXQuery式に置き換え、XQueryTesterjavaプログラムを実行します。

XQuery式

上記のXQuery式の各部分を理解しましょう。

関数の使用

doc("books.xml")

doc()は、XMLソースを見つけるために使用されるXQuery関数の1つです。ここで「books.xml」を渡しました。相対パスを考慮すると、books.xmlはbooks.xqyが存在するのと同じパスにある必要があります。

XPath式の使用

doc("books.xml")/books/book

XQueryは、XPath式を多用して、検索が行われるXMLの必要な部分を見つけます。ここでは、booksノードで使用可能なすべてのbookノードを選択しました。

オブジェクトを反復します

for $x in doc("books.xml")/books/book

XQueryはxmlデータをオブジェクトとして扱います。上記の例では、$ xは選択されたノードを表し、forループはノードのコレクションを繰り返し処理します。

条件を適用します

where $x/price>30

$ xは選択されたノードを表すため、「/」は必要な要素の値を取得するために使用されます。「where」句は、検索結果に条件を設定するために使用されます。

結果を返す

return $x/title

$ xは選択されたノードを表すため、「/」は必要な要素、価格、タイトルの値を取得するために使用されます。「return」句は、検索結果から要素を返すために使用されます。

FLWORは、「For、Let、Where、Order by、Return」の頭字語です。次のリストは、FLWOR式でそれらが何を説明するかを示しています-

  • F -For-すべてのノードのコレクションを選択します。

  • L --Let-結果をXQuery変数に入れます。

  • W -ここで-条件で指定されたノードを選択します。

  • O -並べ替え-基準に従って指定されたノードを並べ替えます。

  • R -戻り値-最終結果を返します。

以下は、書籍のコレクションに関する情報を含むサンプルXMLドキュメントです。FLWOR式を使用して、価格が30を超える本のタイトルを取得します。

books.xml

<?xml version="1.0" encoding="UTF-8"?>
<books>
   
   <book category="JAVA">
      <title lang="en">Learn Java in 24 Hours</title>
      <author>Robert</author>
      <year>2005</year>
      <price>30.00</price>
   </book>
   
   <book category="DOTNET">
      <title lang="en">Learn .Net in 24 hours</title>
      <author>Peter</author>
      <year>2011</year>
      <price>70.50</price>
   </book>
   
   <book category="XML">
      <title lang="en">Learn XQuery in 24 hours</title>
      <author>Robert</author>
      <author>Peter</author> 
      <year>2013</year>
      <price>50.00</price>
   </book>
   
   <book category="XML">
      <title lang="en">Learn XPath in 24 hours</title>
      <author>Jay Ban</author>
      <year>2010</year>
      <price>16.50</price>
   </book>
   
</books>

次のXqueryドキュメントには、上記のXMLドキュメントで実行されるクエリ式が含まれています。

books.xqy

let $books := (doc("books.xml")/books/book)
return <results>
{
   for $x in $books
   where $x/price>30
   order by $x/price
   return $x/title
}
</results>

結果

<title lang="en">Learn XQuery in 24 hours</title>
<title lang="en">Learn .Net in 24 hours</title>

結果の確認

結果を確認するには、books.xqy(環境設定の章に記載)の内容を上記のXQuery式に置き換え、XQueryTesterjavaプログラムを実行します。

XQueryは、XMLドキュメントをHTMLページに変換するためにも簡単に使用できます。次の例を見て、XQueryがどのように機能するかを理解してください。

同じbooks.xmlファイルを使用します。次の例では、XQueryを使用してbooks.xmlからデータを抽出し、すべての書籍のタイトルとそれぞれの価格を含むHTMLテーブルを作成します。

books.xml

<?xml version="1.0" encoding="UTF-8"?>
<books>
   
   <book category="JAVA">
      <title lang="en">Learn Java in 24 Hours</title>
      <author>Robert</author>
      <year>2005</year>
      <price>30.00</price>
   </book>
   
   <book category="DOTNET">
      <title lang="en">Learn .Net in 24 hours</title>
      <author>Peter</author>
      <year>2011</year>
      <price>70.50</price>
   </book>
   
   <book category="XML">
      <title lang="en">Learn XQuery in 24 hours</title>
      <author>Robert</author>
      <author>Peter</author> 
      <year>2013</year>
      <price>50.00</price>
   </book>
   
   <book category="XML">
      <title lang="en">Learn XPath in 24 hours</title>
      <author>Jay Ban</author>
      <year>2010</year>
      <price>16.50</price>
   </book>
   
</books>

以下に示すのは、上記のXMLドキュメントで実行されるXquery式です。

books.xqy

let $books := (doc("books.xml")/books/book)
return <table><tr><th>Title</th><th>Price</th></tr>
{
   for $x in $books   
   order by $x/price
   return <tr><td>{data($x/title)}</td><td>{data($x/price)}</td></tr>
}
</table>
</results>

結果

<table>
   <tr>
      <th>Title</th>
      <th>Price</th>
   </tr>
   <tr>
      <td>Learn XPath in 24 hours</td>
      <td>16.50</td>
   </tr>   
   <tr>
      <td>Learn Java in 24 Hours</td>
      <td>30.00</td>
   </tr>
   <tr>
      <td>Learn XQuery in 24 hours</td>
      <td>50.00</td>
   </tr>   
   <tr>
      <td>Learn .Net in 24 hours</td>
      <td>70.50</td>
   </tr>
</table>

結果の確認

結果を確認するには、books.xqy(環境設定の章に記載)の内容を上記のXQuery式に置き換え、XQueryTesterjavaプログラムを実行します。

XQuery式

ここでは、次のXQuery式を使用しました-

  • title要素の値を評価するdata()関数、および

  • {}演算子は、XQueryプロセッサにdata()を関数と見なすように指示します。{}演算子が使用されていない場合、data()は通常のテキストとして扱われます。

XQueryはXPathに準拠しています。XPath式を使用して、XMLコレクションの検索結果を制限します。XPathの使用方法の詳細については、XPathチュートリアルを参照してください。

書籍のリストを取得するために以前に使用した次のXPath式を思い出してください。

doc("books.xml")/books/book

XPathの例

books.xmlファイルを使用して、XQueryを適用します。

books.xml

<?xml version="1.0" encoding="UTF-8"?>
<books>
   
   <book category="JAVA">
      <title lang="en">Learn Java in 24 Hours</title>
      <author>Robert</author>
      <year>2005</year>
      <price>30.00</price>
   </book>
   
   <book category="DOTNET">
      <title lang="en">Learn .Net in 24 hours</title>
      <author>Peter</author>
      <year>2011</year>
      <price>40.50</price>
   </book>
   
   <book category="XML">
      <title lang="en">Learn XQuery in 24 hours</title>
      <author>Robert</author>
      <author>Peter</author> 
      <year>2013</year>
      <price>50.00</price>
   </book>
   
   <book category="XML">
      <title lang="en">Learn XPath in 24 hours</title>
      <author>Jay Ban</author>
      <year>2010</year>
      <price>16.50</price>
   </book>
   
</books>

ここでは、価格値が30を超える本のタイトルを表示するという同じ目的を満たすXQueryステートメントの3つのバージョンを示しました。

XQuery –バージョン1

(: read the entire xml document :)
let $books := doc("books.xml")

for $x in $books/books/book
where $x/price > 30
return $x/title

出力

<title lang="en">Learn .Net in 24 hours</title>
<title lang="en">Learn XQuery in 24 hours</title>

XQuery –バージョン2

(: read all books :)
let $books := doc("books.xml")/books/book

for $x in $books
where $x/price > 30
return $x/title

出力

<title lang="en">Learn .Net in 24 hours</title>
<title lang="en">Learn XQuery in 24 hours</title>

XQuery –バージョン3

(: read books with price > 30 :)
let $books := doc("books.xml")/books/book[price > 30]

for $x in $books
return $x/title

出力

<title lang="en">Learn .Net in 24 hours</title>
<title lang="en">Learn XQuery in 24 hours</title>

結果を確認する

結果を確認するには、books.xqy(環境設定の章に記載)の内容を上記のXQuery式に置き換え、XQueryTesterjavaプログラムを実行します。

シーケンスは、アイテムが類似または異なるタイプである可能性があるアイテムの順序付けられたコレクションを表します。

シーケンスの作成

シーケンスは、引用符または二重引用符と数字の中に文字列を含む括弧を使用して作成されます。XML要素はシーケンスのアイテムとしても使用できます。

XQuery式

let $items := ('orange', <apple/>, <fruit type="juicy"/>, <vehicle type="car">sentro</vehicle>, 1,2,3,'a','b',"abc")
let $count := count($items)
return
<result>
   <count>{$count}</count>
   
   <items>
      {
	     for $item in $items
         return <item>{$item}</item>
      }
   </items>
   
</result>

出力

<result>
   <count>10</count>
   <items>
      <item>orange</item>
      <item>
         <apple/>
      </item>
      <item>
         <fruit type="juicy"/>
      </item>
      <item>
         <vehicle type="car">Sentro</vehicle>
      </item>
      <item>1</item>
      <item>2</item>
      <item>3</item>
      <item>a</item>
      <item>b</item>
      <item>abc</item>
   </items>
</result>

シーケンスのアイテムの表示

シーケンスの項目は、インデックスまたは値を使用して、1つずつ繰り返すことができます。上記の例では、シーケンスの項目を1つずつ繰り返しました。他の2つの方法の実際を見てみましょう。

XQuery式(インデックス)

let $items := (1,2,3,4,5,6)
let $count := count($items)
return
   <result>
      <count>{$count}</count>
      
      <items>
      {
         for $item in $items[2]
         return <item>{$item}</item>
      }
      </items>
      
   </result>

出力

<result>
   <count>6</count>
   <items>
      <item>2</item>
   </items>
</result>

XQuery式(値)

let $items := (1,2,3,4,5,6)
let $count := count($items)
return
   <result>
      <count>{$count}</count>
      
      <items>
      {
         for $item in $items[. = (1,2,3)]
         return <item>{$item}</item>
      }
      </items>
      
   </result>

出力

<result>
   <count>6</count>
   <items>
      <item>1</item>
      <item>2</item>
      <item>3</item>
   </items>
</result>

次の表に、XQueryが提供する一般的に使用されるシーケンス関数を示します。

シニア番号 名前と説明
1

count($ seq as item()*)

シーケンス内のアイテムをカウントします。

2

sum($ seq as item()*)

シーケンス内のアイテムの合計を返します。

3

avg($ seq as item()*)

シーケンス内のアイテムの平均を返します。

4

min($ seq as item()*)

シーケンス内の最小値のアイテムを返します。

5

max($ seq as item()*)

シーケンス内の最大値のアイテムを返します。

6

個別の値($ seq as item()*)

シーケンスから選択した個別のアイテムを返します。

7

subsequence($ seq as item()*、$ startingLoc as xs:double、$ length as xs:double)

指定されたシーケンスのサブセットを返します。

8

insert-before($ seq as item()*、$ position as xs:integer、$ inserts as item()*)

アイテムを順番に挿入します。

9

remove($ seq as item()*、$ position as xs:integer)

シーケンスからアイテムを削除します。

10

reverse($ seq as item()*)

逆の順序を返します。

11

index-of($ seq as anyAtomicType()*、$ target as anyAtomicType())

シーケンス内のアイテムの可用性を示す整数としてインデックスを返します。

12

最終()

述語式で使用される場合、シーケンスの最後の要素を返します。

13

ポジション()

FLOWR式で使用され、シーケンス内のアイテムの位置を取得します。

次の表に、XQueryが提供する一般的に使用される文字列操作関数を示します。

シニア番号 名前と説明
1

string-length($ string as xs:string)as xs:integer

文字列の長さを返します。

2

concat($ input as xs:anyAtomicType?)as xs:string

連結された文字列を出力として返します。

3

string-join($ sequence as xs:string *、$ delimiter as xs:string)as xs:string

区切り文字で区切られたシーケンス内のアイテムの組み合わせを返します。

次の表に、XQueryが提供する一般的に使用される日付関数を示します。

シニア番号 名前と説明
1

現在の日付()

現在の日付を返します。

2

現在の時刻()

現在の時刻を返します。

3

current-dateTime()

現在の日付と現在の時刻の両方を返します。

以下は、XQueryによって提供される一般的に使用される正規表現関数のリストです。

シニア番号 名前と説明
1

一致($ input、$ regex)

入力が指定された正規表現と一致する場合はtrueを返します。

2

replace($ input、$ regex、$ string)

一致した入力文字列を指定された文字列に置き換えます。

3

tokenize($ input、$ regex)

正規表現に一致するアイテムのシーケンスを返します。

XQueryは、渡された入力値の有効性をチェックするための非常に便利なif-then-else構造を提供します。以下に、if-then-else構文の構文を示します。

構文

if (condition) then
 ... 
else
 ...

次のbooks.xmlファイルを使用し、if-then-else構文を含むXQuery式を適用して、価格値が30を超える本のタイトルを取得します。

books.xml

<?xml version="1.0" encoding="UTF-8"?>
<books>
   <book category="JAVA">
      <title lang="en">Learn Java in 24 Hours</title>
      <author>Robert</author>
      <year>2005</year>
      <price>30.00</price>
   </book>
   
   <book category="DOTNET">
      <title lang="en">Learn .Net in 24 hours</title>
      <author>Peter</author>
      <year>2011</year>
      <price>40.50</price>
   </book>
   
   <book category="XML">
      <title lang="en">Learn XQuery in 24 hours</title>
      <author>Robert</author>
      <author>Peter</author>
      <year>2013</year>
      <price>50.00</price>
   </book>
   
   <book category="XML">
      <title lang="en">Learn XPath in 24 hours</title>
      <author>Jay Ban</author>
      <year>2010</year>
      <price>16.50</price>
   </book>
</books>

次のXQuery式は、上記のXMLドキュメントに適用されます。

books.xqy

<result>
{
   if(not(doc("books.xml"))) then (
      <error>
         <message>books.xml does not exist</message>
      </error>
   )
   else ( 
      for $x in doc("books.xml")/books/book	
      where $x/price>30
      return $x/title
   )
}
</result>

出力

<result>
   <title lang="en">Learn .Net in 24 hours</title>
   <title lang="en">Learn XQuery in 24 hours</title>
</result>

結果を確認する

結果を確認するには、books.xqy(環境設定の章に記載)の内容を上記のXQuery式に置き換え、XQueryTesterjavaプログラムを実行します。

XQueryは、カスタム関数を作成する機能を提供します。以下にリストされているのは、カスタム関数を作成するためのガイドラインです。

  • キーワードを使用する declare function 関数を定義します。

  • 現在のXMLスキーマで定義されているデータ型を使用する

  • 関数本体を中括弧で囲みます。

  • 関数の名前の前にXML名前空間を付けます。

次の構文は、カスタム関数の作成時に使用されます。

構文

declare function prefix:function_name($parameter as datatype?...)
as returnDatatype?
{
   function body...
};

次の例は、XQueryでユーザー定義関数を作成する方法を示しています。

XQuery式

declare function local:discount($price as xs:decimal?,$percentDiscount as xs:decimal?)
as xs:decimal? {
   let $discount := $price - ($price * $percentDiscount div 100) 
   return $discount
};

let $originalPrice := 100

let $discountAvailed := 10

return ( local:discount($originalPrice, $discountAvailed))

出力

90

結果を確認する

結果を確認するには、books.xqy(環境設定の章に記載)の内容を上記のXQuery式に置き換え、XQueryTesterjavaプログラムを実行します。