SQL Server 2012中带XML命名空间的Open XML取值问题求助
解决SQL Server 2012中OpenXML处理带命名空间XML的问题
嘿,这个问题我之前也碰到过!当XML加上默认命名空间后,OpenXML就找不到节点了——原因是SQL Server的OpenXML默认不会识别未声明的命名空间,得显式告诉它怎么处理这个命名空间才行。我给你两个可行的解决方案:
方案一:给OpenXML显式声明命名空间
你需要在调用sp_xml_preparedocument时,把默认命名空间映射到一个前缀,然后在XPath查询里使用这个前缀来定位元素。以下是修改后的完整代码:
USE grails GO DECLARE @XML AS XML, @hDoc AS INT, @SQL NVARCHAR (MAX), @rootxmlns varchar(100) -- 补全你的XML内容(示例里添加了子元素方便测试) SELECT @XML = N'<order xmlns="somenamspace/2006-10-31" order-no="00000001"> <order-date>2024-05-20</order-date> <customer-id>CUST001</customer-id> </order>' -- 将默认命名空间映射到前缀ns SET @rootxmlns = '<root xmlns:ns="somenamspace/2006-10-31"/>' -- 初始化XML文档句柄,同时传入命名空间声明 EXEC sp_xml_preparedocument @hDoc OUTPUT, @XML, @rootxmlns -- 使用OpenXML查询,注意用ns前缀定位命名空间下的元素 SELECT * FROM OPENXML(@hDoc, '/ns:order', 2) WITH ( [order-no] VARCHAR(20) '@order-no', -- *注意:默认命名空间不会应用到属性,直接引用即可* OrderDate DATE 'ns:order-date', CustomerID VARCHAR(10) 'ns:customer-id' ) -- 记得释放XML文档句柄,避免内存泄漏 EXEC sp_xml_removedocument @hDoc
关键要点:
- 必须通过
sp_xml_preparedocument的第三个参数声明命名空间,把默认命名空间绑定到一个前缀(比如示例中的ns) - 在XPath路径和子元素引用中,必须加上这个前缀(比如
/ns:order、ns:order-date) - XML属性不需要加前缀,因为W3C规范里默认命名空间不会作用于属性
方案二:使用XML数据类型的内置方法(更简洁)
如果不需要用OpenXML,也可以直接用SQL Server XML类型的.value()方法配合WITH XMLNAMESPACES声明,代码更简洁直观:
USE grails GO DECLARE @XML AS XML SELECT @XML = N'<order xmlns="somenamspace/2006-10-31" order-no="00000001"> <order-date>2024-05-20</order-date> <customer-id>CUST001</customer-id> </order>' -- 声明默认命名空间 ;WITH XMLNAMESPACES (DEFAULT 'somenamspace/2006-10-31') SELECT @XML.value('(/order/@order-no)[1]', 'VARCHAR(20)') AS [order-no], @XML.value('(/order/order-date)[1]', 'DATE') AS OrderDate, @XML.value('(/order/customer-id)[1]', 'VARCHAR(10)') AS CustomerID
这种方法不需要处理文档句柄,直接通过命名空间声明后就可以像无命名空间时一样写XPath,非常方便。
内容的提问来源于stack exchange,提问作者Pinaki Mukherjee
相关产品推荐
相关产品推荐

