exist-db中带TEI命名空间的XML文档REST查询返回空的解决方法
解决exist-db中带命名空间XML文档的查询问题
这个问题是XPath处理命名空间的典型场景——你的XML元素都属于http://www.tei-c.org/ns/1.0命名空间,但默认的XPath查询会把无前缀的元素名当成无命名空间的节点,所以//div/p找不到任何结果。下面给你几种无需移除命名空间的解决方案:
方法1:显式绑定命名空间前缀
这是最规范的做法,在XQuery查询开头声明命名空间前缀,然后用前缀限定元素名:
declare namespace tei="http://www.tei-c.org/ns/1.0"; //tei:div/tei:p
对应的REST请求编码后是:
/data?_query=declare%20namespace%20tei%3D%22http%3A%2F%2Fwww.tei-c.org%2Fns%2F1.0%22%3B%2F%2Ftei%3Adiv%2Ftei%3Ap
方法2:匹配本地名称(忽略命名空间)
如果只是临时查询,或者确定不会有其他命名空间的同名元素,可以用local-name()函数匹配元素的本地名称,绕过命名空间检查:
//*[local-name()='div']/*[local-name()='p']
对应的REST请求编码后是:
/data?_query=%2F%2F*%5Blocal-name%28%29%3D%27div%27%5D%2F*%5Blocal-name%28%29%3D%27p%27%5D
⚠️ 注意:这种方法可能会匹配到其他命名空间下的同名元素,适合简单场景使用。
方法3:设置默认元素命名空间
你可以在查询开头声明默认元素命名空间,这样所有无前缀的元素名都会自动关联到这个命名空间:
declare default element namespace "http://www.tei-c.org/ns/1.0"; //div/p
对应的REST请求编码后是:
/data?_query=declare%20default%20element%20namespace%20%22http%3A%2F%2Fwww.tei-c.org%2Fns%2F1.0%22%3B%2F%2Fdiv%2Fp
这种方法和你移除命名空间后的查询体验一致,但保留了文档的命名空间结构。
为什么原查询失败?
当你的XML根节点带有xmlns="http://www.tei-c.org/ns/1.0"时,所有子元素(包括div、p)都会继承这个命名空间。而你原查询中的//div/p没有指定命名空间,XPath会默认查找无命名空间的div和p元素,自然返回空结果。
内容的提问来源于stack exchange,提问作者user3712940
相关产品推荐
相关产品推荐

