namespace-uri()函数返回节点实际归属的命名空间URI而非前缀,语法为namespace-uri(node),默认作用于当前节点;它不能枚举文档中所有命名空间声明,仅能查询已有节点的URI。

namespace-uri() 函数用于返回指定节点的命名空间 URI(即命名空间的地址,如 http://www.w3.org/1999/xhtml),而不是前缀(如 html 或 xs)。它本身不“获取”命名空间声明,而是读取节点**实际归属的命名空间 URI**——这个 URI 是由该节点被创建时所处的上下文(比如元素的 xmlns 或带前缀的 xmlns:prefix="..." 声明)决定的。
怎么用 namespace-uri() 获取节点的命名空间 URI
语法很简单:namespace-uri(node)。如果不传参数,默认作用于当前上下文节点(.)。
-
获取当前元素的命名空间 URI:直接写
namespace-uri()或namespace-uri(.) -
获取某个子元素的命名空间 URI:比如
namespace-uri(child::book)或namespace-uri(./book) -
配合谓词筛选特定命名空间的节点:例如
//book[namespace-uri() = 'http://example.com/ns'],只选属于该 URI 的book元素
注意:namespace-uri() 返回的是 URI,不是前缀
命名空间前缀(如 xs:、ex:)只是别名,可变且无语义;真正起作用的是 URI。同一个 URI 可以用不同前缀声明,namespace-uri() 对所有情况都返回相同的 URI 字符串。
例如以下 XML 片段:
对 ex:item 节点执行 namespace-uri(),结果是 "http://example.com/ns",不是 "ex"。
常见误区:它不能列出文档中所有声明的命名空间
namespace-uri() 是节点级函数,只能查**已有节点**的归属命名空间。它无法枚举根元素上写的全部 xmlns:xxx="..." 声明(尤其是未被任何节点使用的声明)。XPath 1.0 / 2.0 标准中没有内置函数能“遍历命名空间表”。如果需要获取所有声明,得靠宿主语言(如 Python 的 lxml、Java 的 JAXP)通过 DOM/SAX 接口专门提取。
在带命名空间的文档中写 XPath 要注意上下文绑定
很多 XPath 引擎(如浏览器 DevTools、lxml、Saxon)默认不自动识别 XML 中的 xmlns 前缀绑定。即使节点有命名空间,直接写 //book 通常匹配不到——因为无前缀的 book 被视为“无命名空间”,而实际节点属于某 URI。
- 正确做法:注册命名空间前缀(如把
ex绑定到http://example.com/ns),再用//ex:book - 或绕过前缀,用
local-name()+namespace-uri()组合:例如//*[local-name()='book' and namespace-uri()='http://example.com/ns']
基本上就这些。记住核心:namespace-uri() 是“读值”函数,反映节点真实归属,不是“解析声明”的工具。用它定位节点很可靠,但想反向查文档里写了哪些 xmlns,就得换方法。










