掌握 XPath、XQuery 和 XSLT 函数提升开发效率(二)
- 开发工具
- 2天前
- 6热度
- 0评论
XPath、XQuery 和 XSLT 是处理 XML 数据的强大工具。本文将详细介绍这些技术中的常用函数,帮助你在实际开发中更高效地操作 XML 文档。通过学习这些函数,你将能够更灵活地解析、转换和生成 XML 数据,提升开发效率。
1. 基础知识
XPath、XQuery 和 XSLT 都依赖于一组标准函数来处理数据。这些函数涵盖了从基本的数据访问到复杂的错误处理和调试功能。函数的命名空间默认前缀为 fn,其 URI 为 http://www.w3.org/2005/xpath-functions。
2. 数据访问函数
2.1 节点名称和属性
- fn:node-name(node): 返回指定节点的名称。
- fn:nilled(node): 检查节点是否被标记为 nil,返回布尔值。
- fn:data(item, item, ...): 接受一个项目序列并返回相应的原子值序列。
- fn:base-uri() 和 fn:base-uri(node): 返回当前节点或指定节点的 base-uri 属性值。
- fn:document-uri(node): 返回指定节点的 document-uri 属性值。
示例
<book>
<title>XML in Action</title>
<author>John Doe</author>
</book>fn:node-name(/book/title) <!-- 返回 "title" -->
fn:nilled(/book/title) <!-- 返回 false -->
fn:data(/book/author) <!-- 返回 "John Doe" -->
fn:base-uri(/book) <!-- 返回当前节点的 base-uri -->
fn:document-uri(/book) <!-- 返回当前节点的 document-uri -->3. 错误和调试函数
3.1 错误处理
- fn:error(): 抛出一个错误,可选参数包括错误代码、描述和错误对象。
- fn:trace(value, label): 用于调试,记录特定值及其标签。
示例
fn:error(fn:QName('http://example.com/test', 'err:toohigh'), 'Error: Price is too high')上述代码会抛出一个带有错误代码 http://example.com/test#toohigh 和描述 "Error: Price is too high" 的错误。
4. 数值处理函数
4.1 基本数值操作
- fn:number(arg): 将参数转换为数值。
- fn:abs(num): 返回参数的绝对值。
- fn:ceiling(num): 返回大于或等于参数的最小整数。
- fn:floor(num): 返回小于或等于参数的最大整数。
- fn:round(num): 四舍五入参数到最接近的整数。
- fn:round-half-to-even(num): 四舍六入五成双。
示例
fn:number('100') <!-- 返回 100 -->
fn:abs(-3.14) <!-- 返回 3.14 -->
fn:ceiling(3.14) <!-- 返回 4 -->
fn:floor(3.14) <!-- 返回 3 -->
fn:round(3.14) <!-- 返回 3 -->
fn:round-half-to-even(0.5) <!-- 返回 0 -->
fn:round-half-to-even(1.5) <!-- 返回 2 -->5. 字符串处理函数
5.1 基本字符串操作
fn:string(arg): 将参数转换为字符串。
fn:codepoints-to-string(int, int, ...): 根据代码点序列返回字符串。
fn:string-to-codepoints(string): 根据字符串返回代码点序列。
fn:codepoint-equal(comp1, comp2): 比较两个代码点是否相等。
fn:compare(comp1, comp2): 比较两个字符串,返回 -1、0 或 1。
fn:concat(string, string, ...): 连接多个字符串。
fn:string-join((string, string, ...), sep): 使用指定分隔符连接字符串序列。
fn:substring(string, start, len): 返回从指定位置开始的子字符串。
fn:string-length(string): 返回字符串的长度。
fn:normalize-space(string): 去除字符串首尾的空白,并将内部的连续空白替换为单个空格。
fn:normalize-unicode(string): 执行 Unicode 规范化。
fn:upper-case(string): 将字符串转换为大写。
fn:lower-case(string): 将字符串转换为小写。
fn:translate(string1, string2, string3): 将 string1 中的 string2 替换为 string3。
fn:escape-uri(stringURI, esc-res): 对 URI 进行转义。
fn:contains(string1, string2): 检查 string1 是否包含 string2。
fn:starts-with(string1, string2): 检查 string1 是否以 string2 开头。
fn:ends-with(string1, string2): 检查 string1 是否以 string2 结尾。
fn:substring-before(string1, string2): 返回 string2 在 string1 中出现之前的子字符串。
fn:substring-after(string1, string2): 返回 string2 在 string1 中出现之后的子字符串。
fn:matches(string, pattern): 检查 string 是否匹配指定的正则表达式。
fn:replace(string, pattern, replace): 将 string 中匹配 pattern 的部分替换为 replace。
fn:tokenize(string, pattern): 使用正则表达式将字符串分割为多个子字符串。
示例
fn:string(314) <!-- 返回 "314" -->
fn:codepoints-to-string(84, 104, 233, 114, 232, 115, 101) <!-- 返回 "Thérèse" -->
fn:string-to-codepoints("Thérèse") <!-- 返回 84, 104, 233, 114, 232, 115, 101 -->
fn:compare('abc', 'def') <!-- 返回 -1 -->
fn:concat('XPath ', 'is ', 'FUN!') <!-- 返回 "XPath is FUN!" -->
fn:string-join(('We', 'are', 'having', 'fun!'), ' ') <!-- 返回 "We are having fun!" -->
fn:substring('Beatles', 1, 4) <!-- 返回 "Beat" -->
fn:string-length('Beatles') <!-- 返回 7 -->
fn:normalize-space(' The XML ') <!-- 返回 "The XML" -->
fn:upper-case('The XML') <!-- 返回 "THE XML" -->
fn:translate('12:30', '30', '45') <!-- 返回 "12:45" -->
fn:escape-uri("http://example.com/test#car", true()) <!-- 返回 "http%3A%2F%2Fexample.com%2Ftest#car" -->
fn:contains('XML', 'XM') <!-- 返回 true -->
fn:starts-with('XML', 'X') <!-- 返回 true -->
fn:ends-with('XML', 'X') <!-- 返回 false -->
fn:substring-before('12/10', '/') <!-- 返回 "12" -->
fn:substring-after('12/10', '/') <!-- 返回 "10" -->
fn:matches("Merano", "ran") <!-- 返回 true -->
fn:replace("Bella Italia", "l", "*") <!-- 返回 "Be**a Ita*ia" -->
fn:tokenize("XPath is fun", "\s+") <!-- 返回 ("XPath", "is", "fun") -->6. URI 处理函数
6.1 解析和构建 URI
- fn:resolve-uri(relative, base): 解析相对 URI 并返回绝对 URI。
示例
fn:resolve-uri("test.html", "http://example.com/") <!-- 返回 "http://example.com/test.html" -->7. 布尔值处理函数
7.1 基本布尔操作
- fn:boolean(arg): 将参数转换为布尔值。
- fn:not(arg): 取反布尔值。
- fn:true(): 返回 true。
- fn:false(): 返回 false。
示例
fn:boolean(0) <!-- 返回 false -->
fn:not(true()) <!-- 返回 false -->
fn:true() <!-- 返回 true -->
fn:false() <!-- 返回 false -->8. 日期和时间处理函数
8.1 日期和时间组件提取
fn:dateTime(date, time): 将日期和时间组合为 dateTime 类型。
fn:years-from-duration(datetimedur): 提取 duration 的年份部分。
fn:months-from-duration(datetimedur): 提取 duration 的月份部分。
fn:days-from-duration(datetimedur): 提取 duration 的天数部分。
fn:hours-from-duration(datetimedur): 提取 duration 的小时部分。
fn:minutes-from-duration(datetimedur): 提取 duration 的分钟部分。
fn:seconds-from-duration(datetimedur): 提取 duration 的秒数部分。
fn:year-from-dateTime(datetime): 提取 dateTime 的年份部分。
fn:month-from-dateTime(datetime): 提取 dateTime 的月份部分。
fn:day-from-dateTime(datetime): 提取 dateTime 的天数部分。
fn:hours-from-dateTime(datetime): 提取 dateTime 的小时部分。
fn:minutes-from-dateTime(datetime): 提取 dateTime 的分钟部分。
fn:seconds-from-dateTime(datetime): 提取 dateTime 的秒数部分。
fn:timezone-from-dateTime(datetime): 提取 dateTime 的时区部分。
fn:year-from-date(date): 提取 date 的年份部分。
fn:month-from-date(date): 提取 date 的月份部分。
fn:day-from-date(date): 提取 date 的天数部分。
fn:timezone-from-date(date): 提取 date 的时区部分。
fn:hours-from-time(time): 提取 time 的小时部分。
fn:minutes-from-time(time): 提取 time 的分钟部分。
fn:seconds-from-time(time): 提取 time 的秒数部分。
fn:timezone-from-time(time): 提取 time 的时区部分。
fn:adjust-dateTime-to-timezone(datetime, timezone): 调整 dateTime 的时区。
fn:adjust-date-to-timezone(date, timezone): 调整 date 的时区。
fn:adjust-time-to-timezone(time, timezone): 调整 time 的时区。
示例
fn:year-from-dateTime(xs:dateTime("2005-01-10T12:30-04:10")) <!-- 返回 2005 -->
fn:month-from-dateTime(xs:dateTime("2005-01-10T12:30-04:10")) <!-- 返回 01 -->
fn:day-from-dateTime(xs:dateTime("2005-01-10T12:30-04:10")) <!-- 返回 10 -->
fn:hours-from-dateTime(xs:dateTime("2005-01-10T12:30-04:10")) <!-- 返回 12 -->
fn:minutes-from-dateTime(xs:dateTime("2005-01-10T12:30-04:10")) <!-- 返回 30 -->
fn:seconds-from-dateTime(xs:dateTime("2005-01-10T12:30:00-04:10")) <!-- 返回 0 -->
fn:timezone-from-dateTime(xs:dateTime("2005-01-10T12:30-04:10")) <!-- 返回 "-04:10" -->
fn:year-from-date(xs:date("2005-04-23")) <!-- 返回 2005 -->
fn:month-from-date(xs:date("2005-04-23")) <!-- 返回 4 -->
fn:day-from-date(xs:date("2005-04-23")) <!-- 返回 23 -->
fn:timezone-from-date(xs:date("2005-04-23")) <!-- 返回 "" -->
fn:hours-from-time(xs:time("10:22:00")) <!-- 返回 10 -->
fn:minutes-from-time(xs:time("10:22:00")) <!-- 返回 22 -->
fn:seconds-from-time(xs:time("10:22:00")) <!-- 返回 0 -->
fn:timezone-from-time(xs:time("10:22:00")) <!-- 返回 "" -->
fn:adjust-dateTime-to-timezone(xs:dateTime("2005-01-10T12:30-04:10"), xs:dayTimeDuration("PT5H")) <!-- 返回 "2005-01-10T17:30-04:10" -->
fn:adjust-date-to-timezone(xs:date("2005-04-23"), xs:dayTimeDuration("PT5H")) <!-- 返回 "2005-04-23+05:00" -->
fn:adjust-time-to-timezone(xs:time("10:22:00"), xs:dayTimeDuration("PT5H")) <!-- 返回 "15:22:00+05:00" -->9. QName 处理函数
9.1 QName 操作
- fn:QName(namespaceURI, localPart): 创建一个 QName。
- fn:local-name-from-QName(QName): 提取 QName 的本地部分。
- fn:namespace-uri-from-QName(QName): 提取 QName 的命名空间 URI。
- fn:namespace-uri-for-prefix(prefix, element): 获取指定前缀的命名空间 URI。
- fn:in-scope-prefixes(element): 获取元素作用域内的所有前缀。
- fn:resolve-QName(QName, element): 解析 QName。
示例
fn:QName("http://example.com/", "test") <!-- 返回 "http://example.com/:test" -->
fn:local-name-from-QName(fn:QName("http://example.com/", "test")) <!-- 返回 "test" -->
fn:namespace-uri-from-QName(fn:QName("http://example.com/", "test")) <!-- 返回 "http://example.com/" -->
fn:namespace-uri-for-prefix("x", /element) <!-- 返回 "http://example.com/" -->
fn:in-scope-prefixes(/element) <!-- 返回 ("x", "y", "z") -->
fn:resolve-QName("x:test", /element) <!-- 返回 "http://example.com/:test" -->10. 节点处理函数
10.1 节点操作
- fn:name() 和 fn:name(nodeset): 返回当前节点或指定节点集中的第一个节点的名称。
- fn:local-name() 和 fn:local-name(nodeset): 返回当前节点或指定节点集中的第一个节点的本地名称。
- fn:namespace-uri() 和 fn:namespace-uri(nodeset): 返回当前节点或指定节点集中的第一个节点的命名空间 URI。
- fn:lang(lang): 检查当前节点的语言是否匹配指定的语言。
- fn:root() 和 fn:root(node): 返回当前节点或指定节点所属的节点树的根节点。
示例
<book xml:lang="en">
<title>XML in Action</title>
<author>John Doe</author>
</book>fn:name(/book/title) <!-- 返回 "title" -->
fn:local-name(/book/title) <!-- 返回 "title" -->
fn:namespace-uri(/book/title) <!-- 返回 "" -->
fn:lang("en", /book) <!-- 返回 true -->
fn:root(/book/title) <!-- 返回 /book 的根节点 -->11. 序列处理函数
11.1 序列操作
- fn:index-of((item, item, ...), searchitem): 返回项目序列中等于 searchitem 的索引。
- fn:empty(sequence): 检查序列是否为空。
- fn:exists(sequence): 检查序列是否存在。
- fn:count(sequence): 返回序列中的项目数量。
- fn:distinct-values(sequence): 返回序列中的唯一值。
- fn:reverse(sequence): 反转序列。
- fn:subsequence(sequence, start, length): 返回从指定位置开始的子序列。
- fn:unordered(sequence): 返回无序的序列。
- fn:insert-before(sequence, position, insert-item): 在指定位置插入项目。
- fn:remove(sequence, position): 移除指定位置的项目。
- fn:deep-equal(sequence1, sequence2): 检查两个序列是否深度相等。
示例
fn:index-of((1, 2, 3, 4), 3) <!-- 返回 3 -->
fn:empty(() ) <!-- 返回 true -->
fn:exists((1, 2, 3)) <!-- 返回 true -->
fn:count((1, 2, 3)) <!-- 返回 3 -->
fn:distinct-values((1, 2, 2, 3, 3, 3)) <!-- 返回 (1, 2, 3) -->
fn:reverse((1, 2, 3)) <!-- 返回 (3, 2, 1) -->
fn:subsequence((1, 2, 3, 4, 5), 2, 3) <!-- 返回 (2, 3, 4) -->
fn:unordered((1, 2, 3)) <!-- 返回 (1, 2, 3) 或其他无序排列 -->
fn:insert-before((1, 2, 3), 2, 0) <!-- 返回 (1, 0, 2, 3) -->
fn:remove((1, 2, 3), 2) <!-- 返回 (1, 3) -->
fn:deep-equal((1, 2, 3), (1, 2, 3)) <!-- 返回 true -->总结
通过本文,我们详细介绍了 XPath、XQuery 和 XSLT 中的各种函数,涵盖了从基础的数据访问到高级的错误处理和调试功能。这些函数在处理 XML 数据时非常有用,可以帮助你更高效地完成各种任务。希望本文能为你在实际开发中提供有价值的参考。如果你有任何问题或建议,欢迎在评论区留言。