XPath中的QName()函数主要用于处理XML文档中的限定名,它的核心作用是处理符合限定名规范的字符串或者节点名称,返回对应的QName对象,方便后续的节点匹配和名称校验操作。限定名通常由命名空间前缀和本地名称两部分组成,是XML命名空间机制下的核心名称形式。

QName()函数支持的处理类型
QName()函数的参数可以是两种类型,分别是字符串类型和节点类型,不同参数类型的处理逻辑有所区别。
1. 字符串类型参数
当传入的参数是字符串时,该字符串必须符合XML限定名的语法规则。限定名的格式为前缀:本地名称,其中前缀是已经在该XML上下文或者XPath上下文中声明过的命名空间前缀,本地名称是符合XML名称规范的字符串。如果传入的字符串没有前缀,那么会被视为默认命名空间下的本地名称。
需要注意的是,如果传入的字符串前缀没有对应的命名空间声明,QName()函数会返回错误。以下是一个XML示例,用于演示字符串参数的处理:
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:ns="http://www.ipipp.com/ns">
<ns:user>张三</ns:user>
<name>李四</name>
</root>
对应的XPath表达式使用QName()函数处理字符串参数的示例如下:
//QName('ns:user')
上述表达式会匹配到XML中ns:user节点,因为ns前缀已经声明对应命名空间,符合限定名规则。
2. 节点类型参数
当传入的参数是节点时,QName()函数会提取该节点的限定名,返回对应的QName对象。节点的限定名由其命名空间前缀和本地名称组成,和节点本身的名称属性一致。这种方式适合在需要校验节点名称或者提取节点限定名信息的场景下使用。
还是以上面的XML为例,使用节点作为参数的XPath表达式示例如下:
//ns:user[QName(.) = QName('ns:user')]
上述表达式会匹配所有节点名称等于ns:user的节点,这里QName(.)就是提取当前节点的限定名,和字符串构造的QName对象做比较。
QName()函数的使用注意事项
- QName()函数依赖命名空间前缀的声明,无论是字符串参数还是节点参数,涉及的前缀都必须在当前上下文中有对应的命名空间映射,否则会报错。
- 如果传入的字符串是不带前缀的本地名称,那么该名称会被关联到当前上下文的默认命名空间,如果没有默认命名空间,则属于无命名空间的名称。
- QName()函数返回的是QName对象,不能直接和字符串做相等比较,需要和同样由QName()函数生成的QName对象做比较,或者使用名称相关的属性做判断。
和其他名称处理函数的区别
XPath中还有local-name()和namespace-uri()函数,这两个函数分别返回节点的本地名称和命名空间URI,而QName()函数是返回包含前缀和本地名称的完整限定名对象,三者的作用维度不同。如果需要单独处理名称的某一部分,使用另外两个函数更合适,如果需要完整的限定名匹配,使用QName()函数更准确。
以下是一个简单的对比代码示例,展示三个函数的不同返回结果:
//ns:user[local-name() = 'user']
//ns:user[namespace-uri() = 'http://www.ipipp.com/ns']
//ns:user[QName() = QName('ns:user')]
第一个表达式匹配本地名称为user的节点,第二个匹配命名空间URI为指定值的节点,第三个匹配完整限定名为ns:user的节点,三个表达式的匹配范围有所不同。