XPath是在XML文档中查找信息的语言,可以在XML文档中对元素和属性进行遍历。XQuery和XPointer都是建立在XPath之上的。注意:只给出XPath,也可以返回该XPath下的所有节点的集合。
二、 XPath节点:共七种,XML文档被当作节点树对待,树根称为文档节点/根节点。
<bookstore> <book category="CHILDREN"> <title lang="en">Harry Potter</title> <author>J K. Rowling</author> <year>2005</year> <price>29.99</price> </book> </bookstore>
a) 元素:如<author>J K. Rowling</author>;
b) 属性:如lang="en";
三、 XPath节点关系:
a) Parent:父节点;
五、 项目:即基本值或节点。
六、 XPath语法:每个XPath表达式由若干个step组成,除了最后一个step每个都会返回一个set节点,而最后一个step可以返回number、boolean、字符串或node集合。
a) 选取节点:
i. nodename:选取当前节点的所有子节点,如bookstore,选取bookstore元素的所有子节点。
ii. /:从根节点开始选取。
1. 如/bookstore,选取bookstore作为根元素。
iii. //:从匹配选择的当前节点选择文档中的节点,不考虑其位置。
1. 如//book,表示选取所有的book子元素,不考虑其在文档中的位置。
iv. .:选取当前节点,相当于self::。
v. ..:选取当前结点的父节点,相当于parent::。
vi. @:选取属性。如//@lang,表示选取所有lang属性。
b) 谓词(Predicates):嵌在方括号中,用于查找某个特定的/包含某个特定值得节点。
i. /bookstore/book[1]:选取bookstore子元素中的第一个book元素;
d) 选取多条路径:|
i. //book/title | //book/price:选出所有book元素的title和price?选取 book 元素的所有 title 和 price 元素?
七、 XPath轴(Axes):用于定义相对于当前节点的节点集。位置路径可以是绝对的(以/开始)也可以是相对的(以元素/节点开始),每个/分隔一个step。
a) Step:语法——axisName::nodeTest[predicate]绝对路径:
<?xml version="1.0" encoding="ISO-8859-1"?> <bookstore> <book category="COOKING"> <title lang="en">Everyday Italian</title> <author>Giada De Laurentiis</author> <year>2005</year> <price>30.00</price> </book> <book category="CHILDREN"> <title lang="en">Harry Potter</title> <author>J K. Rowling</author> <year>2005</year> <price>29.99</price> </book> <book category="WEB"> <title lang="en">XQuery Kick Start</title> <author>James McGovern</author> <author>Per Bothner</author> <author>Kurt Cagle</author> <author>James Linn</author> <author>Vaidyanathan Nagarajan</author> <year>2003</year> <price>49.99</price> </book> <book category="WEB"> <title lang="en">Learning XML</title> <author>Erik T. Ray</author> <year>2003</year> <price>39.95</price> </book> </bookstore>
doc("books.xml")/bookstore/book[price>35]/count(author)
for $x in doc("books.xml")/bookstore/book return if ($x/@category="CHILDREN") then <child>{data($x/title)}</child> else <adult>{data($x/title)}</adult>
查询结果如下:
<adult>Everyday Italian</adult> <child>Harry Potter</child> <adult>Learning XML</adult> <adult>XQuery Kick Start</adult>
b) 比较操作:
i. 通用比较:=, !=, <, <=, >, >=。<ul> { for $x in doc("books.xml")/bookstore/book order by $x/title return <li>{data($x/title)}. Category: {data($x/@category)}</li> } </ul>
<ul> <li>Everyday Italian. Category: COOKING</li> <li>Harry Potter. Category: CHILDREN</li> <li>Learning XML. Category: WEB</li> <li>XQuery Kick Start. Category: WEB</li> </ul>
ii. 添加属性:使用class添加属性
<ul> { for $x in doc("books.xml")/bookstore/book order by $x/title return <li class="{data($x/@category)}">{data($x/title)}</li> } </ul>
查询结果:
<ul> <li class="COOKING">Everyday Italian</li> <li class="CHILDREN">Harry Potter</li> <li class="WEB">Learning XML</li> <li class="WEB">XQuery Kick Start</li> </ul>
for $x in doc("books.xml")/bookstore/book where $x/price>35 return $x/count(author)
i. 加标签:
xquery version "1.0"; <ul> { for $x in doc("books.xml")/bookstore/book where $x/price>35 return <li>{$x/count(author)}</li> } </ul>
查询结果:
<ul> <li>5</li> <li>1</li> </ul>
<ul> { for $x in doc("books.xml")/bookstore/book/title order by $x return <li>{data($x)}</li> } </ul>
<ul> <li>Everyday Italian</li> <li>Harry Potter</li> <li>Learning XML</li> <li>XQuery Kick Start</li> </ul>
for $x at $i in doc("books.xml")/bookstore/book/title return <book>{$i}. {data($x)}</book>
查询结果:变量i记录了循环的次数
<book>1. Everyday Italian</book> <book>2. Harry Potter</book> <book>3. XQuery Kick Start</book> <book>4. Learning XML</book>
for $x in (10,20), $y in (100,200) return <test>x={$x} and y={$y}</test>
查询结果:
<test>x=10 and y=100</test> <test>x=10 and y=200</test> <test>x=20 and y=100</test> <test>x=20 and y=200</test>
for $x1 in doc("books.xml")/bookstore return for $x2 in $x1/book return $x2/price
for $x2 in (for $x1 in doc("books.xml")/bookstore return $x1/book) return $x2/price
查询结果:
<price>30.00</price> <price>29.99</price> <price>49.99</price> <price>39.95</price>
let $x :=doc("books.xml")/bookstore/book/title return <book>{data($x)}</book>
查询结果:
<book> Everyday ItalianHarry PotterXQuery Kick StartLearning XML </book>
v. where语句:用于过滤绑定的结果,后面常跟条件表达式。
for $x in doc("books.xml")/bookstore/book where $x/price>30 and $x/price<100 return $x
查询结果:
<book category="WEB"> <title lang="en">XQuery Kick Start</title> <author>James McGovern</author> <author>Per Bothner</author> <author>Kurt Cagle</author> <author>James Linn</author> <author>Vaidyanathan Nagarajan</author> <year>2003</year> <price>49.99</price> </book> <book category="WEB"> <title lang="en">Learning XML</title> <author>Erik T. Ray</author> <year>2003</year> <price>39.95</price> </book>
for $x in doc("books.xml")/bookstore/book where $x/price>30 and $x/price<100 order by $x/price descending return $x
declare function local:minPrice( $price as xs:decimal) as xs:decimal { let $disc :=($price) div 100 return ($price - $disc) }; for $x in doc("books.xml")/bookstore/book return <minPrice>{local:minPrice($x/price)}</minPrice>
<minPrice>29.7</minPrice> <minPrice>29.6901</minPrice> <minPrice>49.4901</minPrice> <minPrice>39.5505</minPrice>
目标html为:
<html> <head><title>Book List</title></head> <body> <h1>Book List</h1> <table border="1" cols="3" width="100%"> <tbody> <tr> <td><year>2005</year></td> <td><author>Giada De Laurentiis</author></td> <td><price>30.00</price></td> </tr> <tr> <td><year>2005</year></td> <td><author>J K. Rowling</author></td> <td><price>29.99</price></td> </tr> <tr> <td><year>2003</year></td> <td><author>James McGovern</author> <author>Per Bothner</author> <author>Kurt Cagle</author> <author>James Linn</author> <author>Vaidyanathan Nagarajan</author> </td> <td><price>49.99</price></td> </tr> <tr> <td><year>2003</year></td> <td><author>Erik T. Ray</author></td> <td><price>39.95</price></td> </tr> </tbody> </table> </body> </html>
<html> <head><title>Book List</title></head> <body> <h1>Book List</h1> <table border="1" cols="3" width="100%"> <tbody> { for $x in doc("books.xml")/bookstore/book return <tr> <td>{$x/year}</td> <td>{$x/author}</td> <td>{$x/price}</td> </tr> } </tbody> </table> </body> </html>
<company> <div no="7a"> <dept no="42"> <emp no="123456" name="Whoptimone, Ida"/> <emp no="654321" name="Tirebiter, George"/> </dept> <dept no="51"> <emp no="832953" name="Danger, Nick"/> </dept> </div> <div no="2b"> <dept no="57"> <emp no="283412" name="Boss, Yuda"/> </dept> </div> </company>
目标XML文档:
转换XQuery文档:
(:<company> for $div in doc("company.xml")/company/div return for $dept in $div/dept return for $emp in $dept/emp return <employee id="{data($emp/@no)}"> <name>{data($emp/@name)}</name> <division>{data($div/@no)}</division> <department>{data($dept/@no)}</department> </employee> </company>:) <company> { for $emp in doc("company.xml")//emp return <employee id="{data($emp/@no)}"> <name>{data($emp/@name)}</name> <division>{data($emp /../../@no)}</division> <department>{data($emp /../@no)}</department> </employee> } </company>