Marklogic学习 由浅入深(3)—— XML、XPath、XQuery

时间:2022-01-11 07:53:30

Marklogic预备知识——XML、XPath、XQuery

前言: Marklogic在设计之初就注重于XML文档标准,并将XQuery作为其查询语言。因此在学习marklogic之前,有必要对XML相关知识做下了解。

XML

定义

XML(Extensible Markup Language)可扩展标记语言,设计之初就是为了存储和传输数据,标签本身没有被预定义,符合w3c标准。
同时为了让XML便于解析,XML语法有如下规定:
1. 任何起始标签都应有结束标签。<div>Marklogic</div>
2. 可以采用另一种简化语法,可以在一个标签中同时表示起始和结束标签。<div/>
3. 标签必须按合适的顺序进行嵌套,所以结束标签必须按镜像顺序匹配起始标签。<div><p></p></div>
4. 所有的属性都必须有值。<input name="text">
5. 所有的属性都必须在值的周围加上双引号。

文档声明

XML文档声明向我们声明了这是个XML文件,最简单的声明:<?xml version="1.0" ?>,目前只有1.0版本,还可以规定文档编码<?xml version="1.0" encoding="utf-8" ?>.值得注意的是文档声明不符合XML语法,不属于XML内容,位置始终处于文件第一行。

注释

  1. 注释语法<!--这里写注释-->
  2. 声明之前不能有注释
  3. 注释不能嵌套

举例

<?xml version="1.0" encoding="utf-8" ?>
<books xmlns='http://www.csdn.net/example/book'>
<!--这是一本书的信息-->
<book id="1010596200" category="编程">
<title>Java编程思想</title>
<author>埃克尔</author>
<pubDate>2007-6-1</pubDate>
<pages>880</pages>
<price>30.0</price>
</book>
<!--这是另一本书的信息-->
<book id="1010696100" category="文学">
<title>红楼梦</title>
<author>
<firstAuthor>曹雪芹</firstAuthor>
<secondAuthor>高鹗</secondAuthor>
</author>
<pubDate>2012-9-1</pubDate>
<pages>1606</pages>
<price>41.5</price>
</book>
</books>

XPath

XPath即XML路径语言,可在 XML 文档中对元素和属性进行遍历。它包含一个标准的函数库,符合w3c标准。

节点

在XPath 中,有如下七种类型的节点:
元素element : <title>
属性attribute : id='1010596200'
文本text : 红楼梦
命名空间namespace : xmlns='http://www.csdn.net/example/book'
处理指令processing instruction:强大的函数库
注释comment : <!--这是另一本书的信息-->
文档节点root : 即根节点 <books>

语法

表达式 描述
nodename 选取此节点的所有子节点。
/ 从根节点选取。
// 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。
. 选取当前节点。
.. 选取当前节点的父节点。
@ 选取属性。

举例

表达式 描述
books 选取 books 元素的所有子节点。
/books 选取根元素 bookstore。
books//title 选取属于 books 的子元素的所有 title 元素。
//price 选取所有 price 元素。
books/book[1] 选取属于 books 子元素的第一个 book 元素。
/bookstore/book[price>35.0] 选取所有单价大于35的 book 元素。
//@category 选取所有名为 category 的属性。
//* 选取文档中的所有元素。
/books/book/title/text() 选取文档所有 title 值。
fn:count(/books/book) 计算书的数量,为2本。

XQuery

XQuery = XML Query,是W3C所制定的一套标准,用来从XML文档中提取信息。XQuery 相对于 XML,等同于 SQL 相对于数据库。

基础语法

  • XQuery 对大小写敏感
  • XQuery 的元素、属性以及变量必须是合法的 XML 名称。
  • XQuery 字符串值可使用单引号或双引号。
  • XQuery 变量由 “$”并跟随一个名称来进行定义,如,$str
  • XQuery 注释被 (: 和 :) 分割,例如,(: 这是XQuery 注释 :)

FLWOR 表达式

这里的FLWOR是由XQuery的五个常用关键词for、let、where、order by、return首字母合并而来,音同单词‘flower’(鲜花),但是写法不同。且FLWOR字母顺序由XQuery语法而定,不可变更。

- for : 将某一节点的下所有元素依次赋值到一变量中。
- let : 语句定义变量。
- where : 语句给出了选取条件。
- order by : 语句定义了排序次序。
- return : 语句规定返回什么内容。
首先,我们需要准备一个“book.xml”文件,数据就是第一节的例子内容。基于第二节的内容,我们已经可以看懂/books/book[price>30]/title就是选取书的单价高于30元的书名,现在你需要知道doc("books.xml")/books/book[price>30]/title表达的是同样的意思。
接下来,我们看一段代码

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

第一行是在做遍历,把 books 元素下的所有 book 元素提取到名为 $x 的变量中;第二行给出判断条件,需要book元素下的price值大于30;第三行返回数据,满足判断条件的title元素。此 FLWOR 表达式所选取的数据和上面的路径表达式是相同的。得到的数据为<title>红楼梦</title>.

条件表达

“if-then-else” 在 XQuery 中做条件选择使用。
请看下面的例子:

    for $x in doc("books.xml")/books/book
return if ($x/@category="文学")
then <Literature>{data($x/title)}</Literature>
else <Programming>{data($x/title)}</Programming>

结果为

<Literature>红楼梦</Literature>
<Programming>Java编程思想</Programming>

请注意 “if-then-else” 的语法:if 表达式后的圆括号是必需的,else 也是必需的,如果else没有语句,仅仅写 “else ()” 也是可以的。

比较

在 XQuery 中,有两种方法来比较值。
通用比较:=, !=, <, <=, >, >=
值的比较:eq、ne、lt、le、gt、ge

这两种比较方法的差异如下:
请看下面的 XQuery 表达式:
books//book/price > 10
如果 price 的值大于 10,上面的表达式的返回值为 true。
books//book/price gt 10
如果仅返回一个price ,且它的值大于 10,那么表达式返回 true。如果不止一个 price 被返回,则会发生错误。
当然这一差异属于XQuery语法,在Marklogic下,没有这一约束。

自定义函数

declare function 前缀:函数名($参数 AS 数据类型) AS 返回的数据类型
{

(: ...函数代码... :)

};

应注意:
- 请使用 declare function 关键词
- 函数名须使用前缀
- 参数的数据类型通常与在 XML Schema 中定义的数据类型一致
- 函数主体须被花括号包围
举个例子:

declare function local:TotalPrice(
$price as xs:decimal?,
$count as xs:int?)

as xs:decimal?
{

let $tp := $price * $count
return $tp
};

上例中,调用函数时,传入书的单价和要购买的本数,即可得出总价。
local:TotalPrice(/books/book[price>30]/price, 2) 返回83.
另:(常见的 XML Schema 数据类型)

Simple Type Comments
string 字符串
int 整数
decimal -1.23, 0, 123.4, 1000.00
boolean true/false
dateTime 2015-12-07T23:20:00.000
QName 带命名空间的XML签名