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内容,位置始终处于文件第一行。
注释
- 注释语法
<!--这里写注释-->
- 声明之前不能有注释
- 注释不能嵌套
举例
<?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签名 |