XML 簡介
XML stands for Extensible Markup Language. It is a text-based markup language derived from Standard Generalized Markup Language (SGML).
XML is a markup language that defines set of rules for encoding documents in a format that is both human-readable and machine-readable. Following example shows how XML markup looks, when embedded in a piece of text −
<message>
<text>Hello, world!</text>
</message>
You can notice there are two kinds of information in the above example −
- Markup (tag)
- The text, or the character data
XML 文件可以使用樹 (tree) 來表示。一個 XML 樹開始於 root element, 並且從 root element 開始其 child elements 的分支。 XML elements 可以有屬性 (attributes),例如下面的例子:
<note date="2023/04/28">
<name>Orange</name>
</note>
The XML document can optionally have an XML declaration. It is written as follows −
<?xml version = "1.0" encoding = "UTF-8"?>
XPath 簡介
XPath (XML Path Language) is an expression language designed to support the query or transformation of XML documents. It was defined by the World Wide Web Consortium (W3C) in 1999.
In XPath, there are seven kinds of nodes: element, attribute, text, namespace, processing-instruction, comment, and root nodes.
The most important kind of expression in XPath is a location path. A location path consists of a sequence of location steps. Each location step has three components:
- an axis
- a node test
- zero or more predicates.
| Full syntax | Abbreviated syntax | Notes |
|---|---|---|
ancestor |
||
ancestor-or-self |
||
attribute
|
@
|
@abc is short for attribute::abc
|
child |
xyz is short for child::xyz
| |
descendant |
||
descendant-or-self
|
//
|
// is short for /descendant-or-self::node()/
|
following |
||
following-sibling |
||
namespace |
||
parent
|
..
|
.. is short for parent::node()
|
preceding |
||
preceding-sibling |
||
self
|
.
|
. is short for self::node()
|
Node tests may consist of specific node names or more general expressions. In the case of an XML document in which the namespace prefix gs has been defined, //gs:enquiry will find all the enquiry elements in that namespace, and //gs:* will find all elements, regardless of local name, in that namespace.
Other node test formats are:
- comment()
- finds an XML comment node, e.g.
<!-- Comment --> - text()
- finds a node of type text excluding any children, e.g. the
helloin<k>hello<m> world</m></k> - processing-instruction()
- finds XML processing instructions such as
<?php echo $a; ?>. In this case,processing-instruction('php')would match. - node()
- finds any node at all.
Predicates, written as expressions in square brackets, can be used to filter a node-set according to some condition. For example, a returns a node-set (all the a elements which are children of the context node), and a[@href='help.php'] keeps only those elements having an href attribute with the value help.php.
XQuery 簡介
XQuery 是由 W3C 定義的查詢語言,程式風格為函數式程式設計 (functional programming), 建立在 XPath 的基礎上,使用 Xpath 表達要查詢的路徑資訊, 專門用於在結構化或半結構化 XML 資料中進行搜尋、操作和轉換,類似 SQL 之於關聯式資料庫。 在 XQuery 3.1 增加了對於 JSON 的支援,所以 XQuery 也可以用來處理 JSON 資料(如果你想要這樣做的話)。
目前 XQuery 的版本如下:
- XQuery 1.0 became a W3C Recommendation on January 23, 2007
- XQuery 3.0 became a W3C Recommendation on April 8, 2014
- XQuery 3.1 became a W3C Recommendation on March 21, 2017
XQuery 所有用於執行計算的 XQuery 語句都是表達式 (expressions),其核心是 FLWOR,用於更複雜的查詢:
- For: 循環存取資料項目。
- Let: 賦值。
- Where: 設定篩選條件。
- Order By: 排序結果。
- Return: 定義輸出結果。
下面是一個 XQuery 的 Hello World 例子:
let $message := 'Hello World!'
return
<results>
<message>{$message}</message>
</results>
下面是一個 XML 檔案 books.xml:
<?xml version="1.0" encoding="UTF-8"?>
<books>
<book category="JAVA">
<title lang="en">Learn Java in 24 Hours</title>
<author>Robert</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="DOTNET">
<title lang="en">Learn .Net in 24 hours</title>
<author>Peter</author>
<year>2011</year>
<price>70.50</price>
</book>
<book category="XML">
<title lang="en">Learn XQuery in 24 hours</title>
<author>Robert</author>
<author>Peter</author>
<year>2013</year>
<price>50.00</price>
</book>
<book category="XML">
<title lang="en">Learn XPath in 24 hours</title>
<author>Jay Ban</author>
<year>2010</year>
<price>16.50</price>
</book>
</books>
XQuery 可以使用 doc() 函數取得 XML 檔案的內容。下面就是一個 XQuery 的例子:
(: XQuery Comment :)
let $books := (doc("books.xml")/books/book)
return <results>
{
for $x in $books
where $x/price>30
order by $x/price
return $x/title
}
</results>
XQuery 可以使用 for 執行迴圈任務,如下面所示:
for $n in 1 to 10
return
<result>{$n}</result>
Sequences represent an ordered collection of items where items can be of similar or of different types. Sequences are created using parenthesis with strings inside quotes or double quotes and numbers as such. XML elements can also be used as the items of a sequence.
Viewing items in a sequence
let $sequence := ('a', 'b', 'c', 'd', 'e', 'f')
let $count := count($sequence)
return
<results>
<count>{$count}</count>
<items>
{
for $item in $sequence
return
<item>{$item}</item>
}
</items>
</results>
XQuery 內建支援 Regular Expressions,下面是一個例子:
let $input := 'TutorialsPoint Simply Easy Learning'
return (
matches($input, 'Hello') = true(),
matches($input, 'T.* S.* E.* L.*') = true()
)
XQuery 使用 if-then-else 支援條件判斷。
<result>
{
for $book in doc("books.xml")/books/book
return
if ($book/@category = "XML") then (
$book/title
)
}
</result>
XQuery 3.0 加入 lambda functions 的支援,下面是一個例子:
let $fn := function($x, $y) { $x + $y }
return $fn(99, 2)
XQuery 3.0 加入 switch 的支援,下面是一個例子:
for $fruit in ("Apple", "Pear", "Peach")
return switch ($fruit)
case "Apple" return "red"
case "Pear" return "green"
case "Peach" return "pink"
default return "unknown"
XQuery 3.0 加入 try catch 的支援,下面是一個例子:
try {
1 + '2'
} catch * {
'Error [' || $err:code || ']: ' || $err:description
}
XQuery 3.0 加入 || operator 作為 String Concatenations 使用,其實際上為 concat() 函數的快捷方式。
'Hello' || ' ' || 'Universe'
XQuery 3.0 加入 Simple Map Operator !,用於將第一個表達式的結果應用於第二個表達式,下面是一個例子:
(1 to 10) ! element node { . }
XQuery 3.1 加入 Arrow Operator operator =>,提供了一種方便的替代語法,用於將函數傳遞給值。 運算子前面的表達式將提供作為箭頭後面函數的第一個參數。
'w e l c o m e' => upper-case() => tokenize() => string-join('-')
下面則是沒有 Arrow Operator operator 之前的寫法:
string-join(tokenize(upper-case('w e l c o m e')), '-')
XQuery 3.1 加入了 Map 與 Array 支援對於 JSON 資料格式的處理。 Map 是將一組鍵與值關聯起來的函數,從而產生一組鍵/值對,用來處理 JSON 的 object。 Array 是將一組位置(以正整數表示的鍵)與值關聯起來的功能。Array 中的第一個位置對應整數 1,用來處理 JSON 的 array。
let $map := map { 'foo': 42, 'bar': 'baz', 123: 456 }
return for-each(map:keys($map), $map)
let $array := array { 48 to 52 }
for $i in 1 to array:size($array)
return $array($i)
Lookup operator 提供了一種語法糖,用於存取 Map 或 Array 元素的值。它以問號 (?) 開頭,後面跟著一個說明符。說明符可以是:
- A wildcard *,
- The name of the key,
- The integer offset, or
- Any other parenthesized expression.
let $map := map { 'R': 'red', 'G': 'green', 'B': 'blue' }
return (
$map?* (: returns all values; same as: map:keys($map) ! $map(.) :),
$map?R (: returns the value for key 'R'; same as: $map('R') :),
$map?('G', 'B') (: returns the values for key 'G' and 'B' :)
)
let $maps := (
map { 'name': 'Guðrún', 'city': 'Reykjavík' },
map { 'name': 'Hildur', 'city': 'Akureyri' }
)
return $maps[?name = 'Hildur'] ?city
XQuery 3.1 提供了 JSON Serialization,下面是一個例子:
declare option output:method 'json';
map { "key": "value" }
XQuery 3.1 使用 fn:parse-json() 執行 JSON deserialization 的工作:
let $json-input := '{ "firstName": "John", "lastName": "Smith", "address": { "city": "New York" }, "phoneNumbers": ["212-732-1234", "646-123-4567"] }'
let $json-data := fn:parse-json($json-input)
return
$json-data
XQuery 3.1 支援讀取外部的 JSON 文件檔案。
let $json-data := fn:json-doc("/path/to/data.json")
return $json-data
也可以將 JSON 轉換為 XML 文件:
let $json-string := '{ "name": "John", "age": 30, "city": "New York" }'
return fn:json-to-xml($json-string)
參考資料
- XML Tutorial
- XPath (Wikipedia)
- XML Path Language (XPath) 3.1
- XQuery (Wikipedia)
- XQuery 3.1: An XML Query Language
- XQuery and XPath Data Model 3.1
- XQuery Tutorial
- XQuery Tutorial
- XQuery (BaseX doc)
沒有留言:
張貼留言
注意:只有此網誌的成員可以留言。