SQL Server中使用OPENXML时如何设置默认命名空间?
在OPENXML中设置默认命名空间的可行方法
问题场景
现有可正常运行的OPENXML代码:
DECLARE @h int; EXEC sp_xml_preparedocument @h OUTPUT, N'<root xmlns:a="urn:1"><a:Elem>T</a:Elem></root>', '<ns xmlns:a="urn:1" />'; --WITH XMLNAMESPACES (DEFAULT 'a') SELECT * FROM openxml(@h, '/root/a:Elem') WITH (Col1 varchar(20) 'text()'); EXEC sp_xml_removedocument @h;
该代码能返回预期结果Col1 = T。但尝试用WITH XMLNAMESPACES (DEFAULT 'a')去掉查询路径中的a:前缀时,代码无法生效。由于继承了大量旧代码,希望在大规模重构前找到OPENXML下设置默认命名空间的方法。
解决方法:修改sp_xml_preparedocument的命名空间参数
WITH XMLNAMESPACES不适用于OPENXML,因为OPENXML的命名空间上下文由sp_xml_preparedocument的第三个参数(命名空间声明文档)决定。只需在这个参数中指定默认命名空间为目标URN,即可在查询路径中省略前缀。
修改后的代码示例:
DECLARE @h int; -- 在命名空间声明文档中设置默认命名空间为urn:1 EXEC sp_xml_preparedocument @h OUTPUT, N'<root xmlns:a="urn:1"><a:Elem>T</a:Elem></root>', '<ns xmlns="urn:1" />'; -- 路径无需前缀,直接匹配默认命名空间下的Elem元素 SELECT * FROM openxml(@h, '/root/Elem') WITH (Col1 varchar(20) 'text()'); EXEC sp_xml_removedocument @h;
如果后续还需要保留a:前缀的映射(比如其他查询要用到),也可以同时保留前缀声明:
DECLARE @h int; EXEC sp_xml_preparedocument @h OUTPUT, N'<root xmlns:a="urn:1"><a:Elem>T</a:Elem></root>', '<ns xmlns="urn:1" xmlns:a="urn:1" />'; SELECT * FROM openxml(@h, '/root/Elem') -- 无前缀匹配默认命名空间 WITH (Col1 varchar(20) 'text()'); EXEC sp_xml_removedocument @h;
原理说明
sp_xml_preparedocument的第三个参数用于定义XML文档解析时的命名空间上下文。当把默认命名空间设为urn:1后,OPENXML会将查询路径中无前缀的元素(如Elem)关联到这个命名空间,和原XML中a:Elem(属于urn:1命名空间)匹配,从而正确返回结果。而WITH XMLNAMESPACES仅作用于XQuery相关的XML方法,对OPENXML不生效。
内容的提问来源于stack exchange,提问作者Peter Haastrup
相关产品推荐
相关产品推荐

