Download presentation
Presentation is loading. Please wait.
1
XPath读书报告 杨睿
2
目前版本 XML Path Language (XPath) 2.0 (Second Edition)
W3C Recommendation 14 December 2010 (Link errors corrected 3 January 2011) (XML Path Language (XPath) 3.0 W3C Working Draft 13 December 2011)
3
什么是 XPath? XPath 使用路径表达式在 XML 文档中进行导航 XPath 包含一个标准函数库
XPath 是 XSLT 中的主要元素 XPath 是一个 W3C 标准
4
XPath 术语 节点(Node) 在 XPath 中,有七种类型的节点:元素、属性、文本、命名空间、处理指令、注释以及文档(根)节点。XML 文档是被作为节点树来对待的。树的根被称为文档节点或者根节点。
6
XPath 术语 基本值(或称原子值,Atomic value) 基本值是无父或无子的节点。 项目(Item) 项目是基本值或者节点。
7
XPath 术语 节点关系 父(Parent) 子(Children) 同胞(Sibling) 先辈(Ancestor)
后代(Descendant)
8
XPath 语法 选取节点 XPath 使用路径表达式在 XML 文档中选取节点。节点是通过沿着路径或者 step 来选取的。 表达式 描述
nodename 选取此节点的所有子节点。 / 从根节点选取。 // 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。 . 选取当前节点。 .. 选取当前节点的父节点。 @ 选取属性。
9
XPath 语法 实例 在下面的表格中,我们已列出了一些路径表达式以及表达式的结果: 路径表达式 结果 bookstore
注释:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径! bookstore/book 选取属于 bookstore 的子元素的所有 book 元素。 //book 选取所有 book 子元素,而不管它们在文档中的位置。 bookstore//book 选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置。 选取名为 lang 的所有属性。
10
XPath 语法 谓语(Predicates) 谓语用来查找某个特定的节点或者包含某个指定的值的节点。 谓语被嵌在方括号中。
11
路径表达式 结果 /bookstore/book[1] 选取属于 bookstore 子元素的第一个 book 元素。 /bookstore/book[last()] 选取属于 bookstore 子元素的最后一个 book 元素。 /bookstore/book[last()-1] 选取属于 bookstore 子元素的倒数第二个 book 元素。 /bookstore/book[position()<3] 选取最前面的两个属于 bookstore 元素的子元素的 book 元素。 选取所有拥有名为 lang 的属性的 title 元素。 选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性。 /bookstore/book[price>35.00] 选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00。 /bookstore/book[price>35.00]/title 选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00。
12
XPath 语法 选取未知节点 XPath 通配符可用来选取未知的 XML 元素。 通配符 描述 * 匹配任何元素节点。 @*
匹配任何属性节点。 node() 匹配任何类型的节点。 路径表达式 结果 /bookstore/* 选取 bookstore 元素的所有子元素。 //* 选取文档中的所有元素。 选取所有带有属性的 title 元素。
13
XPath 语法 选取若干路径 通过在路径表达式中使用“|”运算符,您可以选取若干个路径。 路径表达式 结果
//book/title | //book/price 选取 book 元素的所有 title 和 price 元素。 //title | //price 选取文档中的所有 title 和 price 元素。 /bookstore/book/title | //price 选取属于 bookstore 元素的 book 元素的所有 title 元素,以及文档中所有的 price 元素。
14
XPath Axes 轴可定义相对于当前节点的节点集。 轴名称 结果 ancestor 选取当前节点的所有先辈(父、祖父等)。
ancestor-or-self 选取当前节点的所有先辈(父、祖父等)以及当前节点本身。 attribute 选取当前节点的所有属性。 child 选取当前节点的所有子元素。 descendant 选取当前节点的所有后代元素(子、孙等)。 descendant-or-self 选取当前节点的所有后代元素(子、孙等)以及当前节点本身。 following 选取文档中当前节点的结束标签之后的所有节点。 namespace 选取当前节点的所有命名空间节点。 parent 选取当前节点的父节点。 preceding 选取文档中当前节点的开始标签之前的所有节点。 preceding-sibling 选取当前节点之前的所有同级节点。 self 选取当前节点。
15
XPath Axes 步(step)包括: 轴(axis)定义所选节点与当前节点之间的树关系
节点测试(node-test)识别某个轴内部的节点 零个或者更多谓语(predicate)更深入地提炼所选的节点集 步的语法:
16
XPath Axes 例子 结果 child::book 选取所有属于当前节点的子元素的 book 节点。 attribute::lang
选取当前节点的所有子元素。 attribute::* 选取当前节点的所有属性。 child::text() 选取当前节点的所有文本子节点。 child::node() 选取当前节点的所有子节点。 descendant::book 选取当前节点的所有 book 后代。 ancestor::book 选择当前节点的所有 book 先辈。 ancestor-or-self::book 选取当前节点的所有 book 先辈以及当前节点(如果此节点是 book 节点) child::*/child::price 选取当前节点的所有 price 孙节点。
17
XPath运算符 运算符…… 描述 实例 返回值 | 计算两个节点集 //book | //cd
+ 加法 6 + 4 10 - 减法 6 - 4 2 * 乘法 6 * 4 24 div 除法 8 div 4 = 等于 price=9.80 如果 price 是 9.80,则返回 true。 如果 price 是 9.90,则返回 false。 != 不等于 price!=9.80 如果 price 是 9.90,则返回 true。 如果 price 是 9.80,则返回 false。 < 小于 price<9.80 如果 price 是 9.00,则返回 true。 <= 小于或等于 price<=9.80 > 大于 price>9.80 >= 大于或等于 price>=9.80 如果 price 是 9.70,则返回 false。 or 或 price=9.80 or price=9.70 如果 price 是 9.50,则返回 false。 and 与 price>9.00 and price<9.90 如果 price 是 8.50,则返回 false。 mod 计算除法的余数 5 mod 2 1
18
XPath 2.0 和 XPath 1.0 之间的区别 基于序列而非节点集的新的数据模型
绑定变量的能力,以前的变量绑定在宿主语言(XSLT)中 完全支持 XML Schema 数据类型 很多新功能,包括正则表达式、日期/时间和字符串操作 注释,虽然不是一个重要的特性,但是在调试查询时很方便:测试时可以注释掉路径的一部分
19
XPath 2.0 中的序列 XPath 2.0 将一切都作为序列来处理。序列 是不同类型的项组成的有序集合。
(2, 'declencheur', 5.10) 基本上所有有效的 XPath 1.0 请求在 XPath 2.0 中仍然是有效的。 如: /po:PurchaseOrder/po:ProductList/po:Name 但是,在 XPath 2.0 (这些项可以是 XML 节点)中定位步表示的是序列中的项而不是树中的节点。
20
XPath 2.0 中的序列 该 XPath 将用于清单所示的订单。它计算订单中每一订单行的总金额并返回下面的序列:
(29.99, 89.98, 80, 3.1) <?xml version="1.0" encoding="ISO "?> <po:PurchaseOrder xmlns:po=" <po:Buyer>Pineapplesoft<po:Buyer> <po:Seller>Bookstore<po:Seller> <po:OrderLines> <po:Line> <po:Code type="ISBN"> <po:Code> <po:Quantity>1<po:Quantity> <po:Description>XML by Example<po:Description> <po:Price>29.99<po:Price> </po:Line> <po:Code type="ISBN"> </po:Code> <po:Quantity>2<po:Quantity> <po:Description>Applied XML Solutions<po:Description> <po:Price>44.99</po:Price> <po:Code type="ISBN"> <po:Code> <po:Description>Huit Solutions Concrètes avec XML et Java</po:Description> <po:Price>40.00<po:Price> <po:Description>Internet Magazine<po:Description> <po:Price>3.10<po:Price> </po:OrderLines> <po:PurchaseOrder
21
XPath 2.0 中的序列 首先计算每一行的总金额然后将结果传递给 sum() 函数。但是在 XPath 1.0 中,变量必须在宿主语言(这里是 XSLT)中声明,因此在变量 lines 中创建了临时结果集。然后将变量的内容提供给第二个 XPath 表达式计算订单总值。
22
条件表达式 XPath 2.0 还引入了条件表达式(if)。语法的含义很明确:根据括号中表达式的计算结果为 true 还是 false,表达式返回 then 或 else 部分。
23
限定性表达式 限定性表达式有两种:every 和 some。如果序列中的每一项都符合条件则 every 表达式返回 true,如果序列中至少有一项满足条件表达式则 some 表达式返回 true。 如果对清单中的文档运行将返回 false,因为第四行没有 po:Code 元素。如果将关键字 every 替换为 some,表达式就会返回 true,因为至少有一行包含 po:Code 元素。
24
XPath 2.0 中的序列 XPath 2.0 的强大在于能够将表达式组合起来创建复杂的请求。用不同的公式计算订单总值:只计算包含产品代码的那些行,其他行被忽略掉(大概因为这些产品不能发货)。代码很简单,因为增加一个 if 表达式就足够了,如果不满足条件,该表达式就返回 empty 序列。
25
XPath 2.0 中原子类型系统 除了XPath 1.0的原子类型系统,还包含所有在 XML 架构数据类型规范中定义的数据类型。
XPath 2.0 还定义了两个新的持续时间子类型,即 yearMonthDuration 和 dayTimeDuration。
26
XPath 2.0 中原子类型系统 有几个新的利于类型检查和强制的运算符:instance of、cast as 和 treat as。
该表达式将标识出类型为 xsd:double 的 LineItem 元素的所有子元素。
27
集(序列)操作 pipe ("|")、intersect 以及 except。 (对应集合的并、交、差操作。)
XPath 2.0 为基本列表操纵提供了预期函数:insert、remove、item-at、index-of 以及 subsequence。
28
集(序列)操作 继承了1.0的大部分操作。 印象比较深的是,几个新颖的distinct操作。
29
"to" Range Operator The range operator–to–can be used to generate a sequence of consecutive integers: (1 to 10) returns the sequence: (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) This expression: (1 to 100)[(. mod 10) = 0] returns the sequence: (10, 20, 30, 40, 50, 60, 70, 80, 90, 100) This expression: (1, 2, 10 to 14, 34, 99) returns this disjointed sequence: (1, 2, 10, 11, 12, 13, 14, 34, 99)
30
Feed Nodes into a Function
In XPath 1.0 an expression following a slash identifies node(s). In XPath 2.0 an expression following a slash can be a function. Each value preceding the slash is fed into the function /planets/planet/name/substring(.,1,1) The name of each planet is fed into Output: ("M", "V", "E")
31
XPath 2.0 is a Strongly Typed Language
Each XPath 2.0 function returns a value of a specific datatype. The argument(s) that are passed to the function must be of the required datatype. Also, the XPath 2.0 operators require the operands be of a required datatype. For example, you cannot perform arithmetic operations on strings without explicitly telling the processor to treat your strings like numbers.
32
XML Schema Datatypes XPath 2.0 uses the datatypes defined in the XML Schema Datatypes Specification
34
其他语言增强 现在,在单个步骤中就可以提供多个节点测试,并增强了 XPath 2.0 中位置步骤的方法:
LineItems/(Sku|Price)/text() 在 XPath 1.0 中,需要联合利用以下两个表达式来获得同样的结果: LineItems/Sku/text() | LineItems/Price/text()
35
增强的字符串处理支持 upper-case、lower-case、string-pad、matches、replace 以及 tokenize
36
Comments XPath 2.0 expressions may be commented using this syntax: (: comment :) (: multiply each day by two :) /planets/planet/day/(for $i in . return $i * 2)
37
如果时间足够
38
Different from the Regex in the XML Schema Pattern Facet
Consider this XML Schema element declaration: <element name="Free-text"> <simpleType> <restriction base="string"> <pattern value="Hello" /> </restriction> </simpleType> </element> And suppose this is the input: <Free-text>Hello</Free-text> The input validates against the schema. That is, the string "Hello" matches the regex in the pattern facet. Likewise, using the same input and regex, the matches function succeeds: if (matches(//Free-text, 'Hello')) then 'Success' else 'Failure'
39
Different from the Regex in the XML Schema Pattern Facet
Next, consider this input: <Free-text>He said Hello World</Free-text> The input does not validate against the schema. That is, the string "He said Hello World" does not match the regex in the pattern facet. Conversely, the matches function does succeed: if (matches(//Free-text, 'Hello')) then 'Success' else 'Failure'
40
XSD Regex's are Implicitly Achored
When you give a regex in a pattern facet, there are "implicit anchors" in the regex. The regex "Hello" is actually this: ^Hello$ The $ matches the end of the input The ^ matches the start of the input Thus "Hello" matches only input that starts with H, ends with o, and in between is ello.
41
No Implicit Anchors in XPath Regex's
The regex "Hello" in XPath has no implicit anchors. Any anchors must be explicitly specified. Thus, the regex "Hello" matches any input that contains the string Hello if (matches(//Free-text, 'Hello')) then 'Success' else 'Failure' is equivalent to: if (contains(//Free-text, 'Hello')) then 'Success' else 'Failure'
42
总结&感想 XPath 2.0 为 XML 规范系列的中级阶段。其他规范(如 XQuery和 XSLT)将其用作官方寻址语言,可能还有其他更多规范会这样使用它。 XPath 2.0 在提升功能并尽可能维持向后兼容性的同时,也提高了使用性。 也有人反对使用 XPath 2.0。许多 XML 开发人员对 XPath 2.0 的日趋复杂有些晕头转向。
43
Xpath 3.0 XPath 3.0 is a composable language function composition
recursion
44
a composable language What does that mean? It means that every operator and language construct allows any XPath expression to appear as its operand (subject only to operator precedence and data typing constraints). For example, take this expression: 3 + ____ The plus (+) operator has a left-operand, 3. What can the right-operand be? Answer: any XPath expression! Let's use the max() function as the right-operand: 3 + max(___) Now, what can the argument to the max() function be? Answer: any XPath expression! Let's use a for-loop as its argumen t: 3 + max(for $i in 1 to 10 return ___) Now, what can the return value of the for-loop be? Answer: any XPath expression! Let's use an if-statement: 3 + max(for $i in 1 to 10 return (if ($i gt 5) then $i*3 else $i*2)))
45
function composition let $increment := function($x as xs:integer) {$x + 1}, $double := function($y as xs:integer) {$y * 2}, $compose := function( $a as function(item()*) as item()*, $b as function(item()*) as item()* ) as function(item()*) as item()* {function($c as item()*) as item()* {$b($a($c))}}, $f := $compose($increment, $double) return $f(2)
46
Recursion let $isNegative := function($x as xs:integer) {$x lt 0},
$decrement := function($x as xs:integer) {$x - 1}, $helper := function( $p as function(item()*) as xs:boolean, $f as function(item()*) as item()*, $x as item()*, $helper as function(function(), function(), item()*, function()) as item()* ) as item()* {if ($p($x)) then $x else $helper($p, $f, $f($x), $helper)}, $until := function( $x as item()* {$helper($p, $f, $x, $helper)} return $until($isNegative, $decrement, 3)
Similar presentations