XML, XPath, XQuery

XML, XPath, XQuery
講師: 福田 剛志
[email protected]
http://www.fukudat.com/
データベース設計
1
文書のマークアップの歴史
• 印刷組版のための “青鉛筆”
• ワープロの見た目に関するコマンド
• 内容と見た目の分離
– 内容をマークアップするための汎用タグ (SGML)
– 見た目を制御するスタイルシート (DSSSL)
• WWWの爆発的普及
– HTML: ハイパーテキストの表現の一つ
– XML: SGMLより単純で,HTMLより汎用
– W3Cによる標準化
(HTML 1995, XML 1998, XSL 2001)
データベース設計
2
XML文書の例
住所録
鈴木 一郎
ワシントン州シアトル
090-1234-5678
[email protected]
松井 秀喜
ニューヨーク州ニューヨーク
090-9876-5432
[email protected]
松坂 大輔
マサチューセッツ州ボストン
090-2468-1357
[email protected]
<?xml version=“1.0”?>
<住所録>
<個人 背番号=“51”>
<名前>鈴木 一郎</名前>
<住所>ワシントン州シアトル</住所>
<電話>090-1234-5678</電話>
<メルアド>[email protected]</メルアド>
</個人>
<個人 背番号=“55”>
<名前>松井 秀喜</名前>
<住所>ニューヨーク州ニューヨーク</住所>
<電話>090-9876-5432</電話>
<メルアド>[email protected]</メルアド>
</個人>
<個人 背番号=“18”>
<名前>松坂 大輔</名前>
<住所>マサチューセッツ州ボストン</住所>
<電話>090-2468-1357</電話>
<メルアド>[email protected]</メルアド>
</個人>
</住所録>
データベース設計
3
XML文書の構造
<?xml version=“1.0”?>
<住所録>
<個人 背番号=“51”>
住所録
<名前>鈴木 一郎</名前>
<住所>ワシントン州シアトル</住所>
<電話>090-1234-5678</電話>
<メルアド>[email protected]</メルアド>
個人
個人
</個人>
<個人 背番号=“55”>
<名前>松井 秀喜</名前>
背番号
<住所>ニューヨーク州ニューヨーク</住所>
<電話>090-9876-5432</電話>
51 名前
住所
電話
<メルアド>[email protected]</メルアド>
</個人>
<個人 背番号=“18”>
<名前>松坂 大輔</名前>
<住所>マサチューセッツ州ボストン</住所>
<電話>090-2468-1357</電話>
090ワシントン州
1234鈴木 一郎
<メルアド>[email protected]</メルアド>
シアトル
5678
</個人>
</住所録>
データベース設計
個人
メルアド
ichiro@
mariners.
com
4
XML言語の構成要素
• 要素 (element)
– <要素名> と </要素名> で囲む.
– 要素は入れ子にできる.
• 属性 (attribute)
– 属性名=“属性値”
– 要素に付加的な情報をつける.
• 先頭にXML宣言
– <?xml version=“バージョン番号” ?>
• ルート要素がひとつ
• XML文書にはスキーマがあってもよい
– スキーマとは,どういう要素をどういう順番で使ってよいかを定めた規則
• DTD (Document Type Definition), XML Schema, RelaxNG
Cf. リレーショナル・スキーマ
= テーブルにどのようなカラムがあるか定めた規則
データベース設計
5
XMLの特徴
• データの近くに,データの説明(要素名,属性名)があ
る=自己記述的
例) <住所>ワシントン州シアトル</住所>
• 要素が入れ子にできるので,階層構造が表現できる.
• 要素の順序は重要 (文書なので)
• 要素の有無,出現回数,順序(に自由度を持たせるこ
とができる.
– 半構造データ (semi-structured data)
Cf. リレーション = フラットな表
– 入れ子は許されない
– すべての行は同じ属性(要素)を持つ
だから毎回記述しない
– 行の順序は考慮しない
データベース設計
6
文書型定義 (Document Type Definition; DTD)
•
XML文書のデータ構造を定義する
– 許される要素とその順序,回数などを規定
– なくてもよい
– “<!DOCTYPE ルート要素 [” で始まり “]>” で終わる
•
要素型宣言
– <!ELEMENT 要素名 構成要素>
– 構成要素の種類
• EMPTY: それ以上の子要素がない
• ANY: その下位に任意の構造を許す
• 子要素の正規表現
正規表現
例) <!ELEMENT 個人 (名前, (住所|電話|メルアド)*)>
• #PCDATA: 文字列データ
•
属性リスト宣言
– <!ATTLIST 要素名 属性名 属性値の候補または型 デフォルト値>
例) <!ATTLIST 名前 背番号 CDATA #IMPLIED>
•
エンティティ宣言
– <!ENTITY % 名前 “定義”>
– <!ENTITY 名前 “定義”>
データベース設計
7
DTDの例
<?xml version=“1.0”?>
<住所録>
<個人 背番号=“51”>
<名前>鈴木 一郎</名前>
<住所>ワシントン州シアトル</住所>
<電話>090-1234-5678</電話>
<メルアド>[email protected]</メルアド>
</個人>
<個人 背番号=“55”>
<名前>松井 秀喜</名前>
<住所>ニューヨーク州ニューヨーク</住所>
<電話>090-9876-5432</電話>
<メルアド>[email protected]</メルアド>
</個人>
<個人 背番号=“18”>
<名前>松坂 大輔</名前>
<住所>マサチューセッツ州ボストン</住所>
<電話>090-2468-1357</電話>
<メルアド>[email protected]</メルアド>
</個人>
</住所録>
<!DOCTYPE 住所録 [
<!ELEMENT 住所録 (個人*)>
<!ELEMENT 個人 (名前, (住所|電話|メルアド)*)>
<!ELEMENT 名前 (#PCDATA)>
<!ATTLIST 名前 背番号 CDATA #IMPLIED>
<!ELEMENT 住所 (#PCDATA)>
<!ELEMENT 電話 (#PCDATA)>
<!ELEMENT メルアド (#PCDATA)>
]>
データベース設計
8
データベースの歴史
• 初期のデータベースは明示的な“ナビゲーショ
ン”が必要であった
• 1980年ごろからほとんどのビジネスデータは
リレーショナルとなった
– データは一様な行と列を持つテーブルに入る.
– データには固有の順序はない
– アクセスパスは自動的に最適化される
• 標準問合せ言語: SQL
• SELECT price * qty
FROM parts
WHERE name = "Bolt"
データベース設計
PARTS
NAME PRICE
QTY
Bolt
0.75
300
Nut
0.12
300
9
データと文書の収束
• WWWの発展がビジネスデータの新しい要件を生んだ
– 注文書,治療記録,保険記録 など
• 多くのデータは文書の性質を持つ
–
–
–
–
固有の順序がある
多様 (すべてのインスタンスは異なる)
まばら (sparse)
階層的 (hierarchical)
• データベースは自己記述的なデータ形式が必要
– XMLは自明な選択
– メタデータが “タグ” としてデータと混在する
– すべての主要なデータベースベンダーはXMLに投資している
データベース設計
10
XMLに対する問い合わせ言語
• XPath 2.0
– XML文書内の一部を指し示す手段
• XSLT 2.0
– XML文書を変換する言語
• XQuery 1.0
– XML文書に対する問い合わせ言語
• XSLT と XQuery は
– データモデル
– 関数ライブラリ
– 型システム
– ナビゲーション (XPath)
を共有する。
XML
Schema
XQuery
XSLT
XPath 2.0
データベース設計
11
XPath
•
•
XML文書内の一部を指し示す手段
ファイルシステムの path と似ている
– “.”: 文脈ノード自身
– “..”: 文脈ノードの親ノード
•
あるノード(文脈ノード)に注目して,そこから指定された道筋(path)で到達で
きる要素を指し示す
– 道筋の一歩一歩 = Location Step
– 既存のものを指し示すことができるが,新しく何かを作ることができない
•
Location Step = 軸 + ノード検査 + 述語
– 軸は7種類
• child, attribute, descendant, ancestor, ancestor-or-self, descendant-or-self, self
– ノード検査はノードの名前,種類を指定する
– 述語は条件式 または 要素番号
•
•
XPath式の値は文書中のノードのリスト
例えば
/company[@location=“Machida”]/employee[secretary]/language[1]
データベース設計
12
XPathの例
• child::xxx は,文脈ノードの子 xxx 要素
• child::xxx[position()>1] は,文脈ノードの最初の子 xxx 以外の,文
脈ノードの子 xxx すべて
• child::* は,文脈ノードの子要素すべて
• child::text() は,文脈ノードの子テキストノードすべて
• child::node() は,そのノード型を問わず,文脈ノードの子すべて
• following-sibling::xxx[position()=1] は,文脈ノードの次の兄弟 xxx
要素
• attribute::name は,文脈ノードの name 属性
• preceding-sibling::xxx[position()=1] は,文脈ノードの前の兄弟
xxx 要素
• attribute::* は,文脈ノードの属性すべて
• /descendant::xxx[position()=42] は,文書の42番目の xxx 要素
• descendant::xxx は,文脈ノードの子孫 xxx 要素
• ancestor::xxx は,文脈ノードの祖先 xxx すべて
• /child::xxx/child::yyy[position()=5]/child::zzz[position()=2] は,
xxx 要素の5番目の yyy の2番目の zzz
• ancestor-or-self::xxx は,文脈ノードの祖先 xxx,および文脈ノード
が xxx 要素である場合にはその文脈ノードも,選択する.
• child::xxx[attribute::aaa="warning"] は,文脈ノードの子 xxx で,
aaa 属性に warning という値をとるものすべて
• descendant-or-self::xxx は,文脈ノードの子孫 xxx,および文脈
ノードが xxx 要素である場合にはその文脈ノードも,選択する.
• child::xxx[attribute::aaa=‘warning’][position()=5] は, 文脈ノード
の子 xxx で aaa 属性に warning という値をとるうち5番目のもの
• self::xxx は,文脈ノードが xxx 要素である場合には文脈ノードを選
択し,そうでない場合には何も選択しない.
• child::xxx[position()=5][attribute::aaa=“warning”] は,文脈ノード
の5番目の子 xxx で aaa 属性に warning という値をとるもの
• child::xxx/descendant::yyy は,文脈ノードの子 xxx 要素の子孫
yyy 要素
• child::xxx[child::yyy='Introduction'] は,文脈ノードの子 xxx で,文
字列値が Introduction に等しい子 yyy を1個以上もつもの
• child::*/child::xxx は,文脈ノードの孫 xxx すべて
• / は,文書ルート
• child::xxx[child::yyy] は,文脈ノードの子 xxx で,1個以上の子 yyy
をもつもの
• /descendant::xxx は,文脈ノードと同じ文書にある xxx 要素すべて
• child::*[self::xxx or self::yyy] は,文脈ノードの子 xxx および子 yyy
• /descendant::xxx/child::yyy は,文脈ノードと同じ文書にある,親に
xxx をもつ yyy 要素すべて
• child::*[self::xxx or self::yyy][position()=last()] は,文脈ノードの子
xxx または yyy のうち最後のもの
• child::xxx[position()=1] は,文脈ノードの最初の子 xxx
• child::xxx[position()=last()] は,文脈ノードの最後の子 xxx
• child::xxx[position()=last()-1] は,文脈ノードの,最後から二番目
の子 xxx
データベース設計
13
XPathの述語3種類
• Bool式 (Boolean Expression)
book[author = “Mark Twain”]
• 数式 (Numeric Expression)
chapter[2]
• 存在検査 (Existence Test)
book[appendix]
person[married]
• これらの3種類のどれなのかを静的には区別できないことがある
– 静的には区別できない = 実行してみないと判らないということ
– 最適化を難しくしている
データベース設計
14
XPath 1.0の設計思想
• なるべく型を少なく
– Boolean, String, Number, Node Set
• なるべくエラーで止まらない(なんとか処理を進める)
– 自動的な型変換を行う
• 結果,暗黙の動作が増えてしまった
– 単一の値が必要なところにリストが来たら最初の要素を使う
– 必要ならばノードを値に変換
– 比較は「存在限定」されている(existentially quantified)
bonus > salary という式の意味は,
∃ b ∈ bonus, ∃s ∈ salary such that ( number(b) > number(s) )
データベース設計
15
XSLT
(Extensible Stylesheet Language Transformations)
• XML文書の変換を記述する言語
• XSLT自身もXMLで表現される
• サブ言語として XPath を使用している
XSLT
による
変換
Source tree
データベース設計
Result tree
16
XSLTの例
<?xml version="1.0" encoding="Shift_JIS"?>
• PAGE というタグが来たら,
<xsl:stylesheet
<HTML><BODY> と
xmlns:xsl="http://www.w3.org/
</BODY></HTML> というタグを出
1999/XSL/Transform" version="1.0">
<xsl:output method="html"
力,その間にテンプレートを繰り返
encoding="Shift_JIS"/>
し適用した結果を含める.
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
• EMPLOYEES というタグが来たら,
<xsl:template match="PAGE">
またテンプレートを繰り返し適用す
<HTML>
る.
<BODY>
<xsl:apply-templates/>
</BODY>
• EMPLOYEE というタグが来たら,
</HTML>
その下の ENAME というタグの値
</xsl:template>
<xsl:template match="EMPLOYEES">
と <BR/> を出力する
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="EMPLOYEE">
<xsl:value-of select="ENAME"/><BR/>
</xsl:template>
</xsl:stylesheet>
17
データベース設計
XQueryの誕生
• QL ’98 国際会議 (Boston)
– 約50個の XML問い合わせ言語の提案があった
• XML Query Working Group
– W3C により 1999年に設立
– 約30社から代表が参加
– QL ’98 の提案を調査し,新しい提案を作成
– 同時に SQL の拡張という選択も検討
– その結果,新言語“XQuery” を開発することを決定
データベース設計
18
XQueryの設計原理
• クロージャー (閉包)
– データモデルに対する操作がそのデータモデル内で閉じてい
る (Cf. 有理数と四則演算)
• 構成的
– XQueryは(数種類の)式の組み合わせでできている
– 式には副作用がない
– 式を組み合わせて式が作られる
• 既存のXML標準との互換性を考慮
– XML Schema の型システム
– XML Namespace の名前付け規則
– XPath によるナビゲーション
データベース設計
19
XQuery Data Model (XDM)
XML文書
(Linear Text)
構文解析
妥当性検証による型
の付与(オプション)
直列化
XQuery
XDM インスタンス
(Nodes & Atomic Values)
データベース設計
20
XML文書の例<?xml version = "1.0"?>
<!-- Requires one trained person -->
<procedure title = "Removing a light bulb">
<time unit = "sec">15</time>
<step>Grip bulb.</step>
<step>
Rotate it
<warning>slowly</warning>
counterclockwise.
</step>
</procedure>
- と,その XDM による表現
D
procedure
C
time
E
A unit="sec"
A title="Removing a light bulb"
E
E
step
step
E
warning
T
T
T
15
Grip bulb.
Rotate it
E
T
counterclockwise.
T
slowly
XQueryの構文例
•
•
•
•
•
•
繰り返し: for $x in expr1 return expr2
条件分岐: if (test) then expr1 else expr2
存在限定: some $x in expr1 satisfies test2
全量限定: every $x in expr1 satisfies test2
集合演算: union, intersect, except
コンストラクター:
<greeting>Hello</greeting>
<revenue>{ $price * $quantity }</revenue>
データベース設計
23
XQueryの例
入力文書 parts.xml
<part>
<partno>101</partno>
<name>車輪</name>
<color>赤</color>
</part>
<part>
<partno>102</partno>
<name>ギア</name>
<color>緑</color>
</part>
:
入力文書 orders.xml
<order>
<date>2007-11-23</date>
<partno>101</partno>
</order>
<order>
<date>2007-12-24</date>
<partno>101</partno>
</order>
データベース設計
24
XQueryの例(つづき)
• 問い合わせ:
– 赤い色の部品(part)で,少なくとも10件以上のオーダーのあるものの名前
とオーダー数を求めよ。
• 出力結果の例
<popular-red-part>
<name>車輪</name>
<orders>95</orders>
</popular-red-part>
<popular-red-part>
<name>タンク</name>
<orders>123</orders>
</popular-red-part>
データベース設計
25
XQueryの例(つづき)
• 問い合わせ:
– 赤い色の部品(part)で,少なくとも10件以上のオーダーのあ
るものの名前とオーダー数を求めよ。
for $p in fn:doc(“parts.xml”)//part[color=“赤”]
let $o := fn:doc(“order.xml”)//order[partno = $p/partno]
where fn:count($o) >= 10
FLWR (フラワー) と表現される
• For
return
• Let
<popular-red-part>
• Where
• Return
{ $p/name }
<orders>{ fn:count($o) }</orders>
</popular-red-part>
データベース設計
26
XQueryの問題
• Groupingできない
Cf. SQL の group by に相当する機能がない
• Updateができない
– 変換はできるが,元のデータを変更できない
Cf. SQL では insert文,update文, delete文で変更できた
次のバージョンでは改善される予定
データベース設計
27
XQuery処理系の例
• Saxon:
– http://saxon.sourceforge.net/
• AltovaXML:
– http://www.altova.com/altovaxml.html
• DataDirect XQuery:
– http://www.datadirect.com/products/xquery/
データベース設計
28