如何在T-SQL中查询带命名空间的XML获取指定节点值
解决XML命名空间导致的CROSS APPLY无返回行问题
你的问题核心是XML存在默认命名空间,所有子节点都继承了根元素Declaration的命名空间urn:se:customs:datamodel:WCO:Declaration:1,如果查询时不指定这个命名空间,SQL Server会找不到对应节点,导致返回空行。
正确的查询方法
首先用WITH XMLNAMESPACES声明默认命名空间,给它分配一个前缀(比如d),然后在XPath中使用这个前缀访问节点:
-- 声明XML变量(包含完整的Declaration标签) DECLARE @XmlData XML = ' <Declaration xmlns="urn:se:customs:datamodel:WCO:Declaration:1" xmlns:S="http://www.w3.org/2003/05/soap-envelope" xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:md="urn:se:customs:datamodel:WCO:DocumentMetaData:1" xmlns:eia="http://tullverket.se/ei/addressing-1" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <!-- 省略XML内容 --> </Declaration>'; -- 使用命名空间查询 WITH XMLNAMESPACES(DEFAULT 'urn:se:customs:datamodel:WCO:Declaration:1') SELECT ExporterAddressLine.value('(.)[1]', 'VARCHAR(100)') AS ExporterAddressLine FROM @XmlData.nodes('/Declaration/GoodsShipment/Exporter/Address/Line') AS T(ExporterAddressLine);
用CROSS APPLY的场景(XML来自表字段)
如果你的XML存储在表的字段中,比如表名为CustomsDeclarations,字段名为XmlContent,可以这样用CROSS APPLY:
WITH XMLNAMESPACES(DEFAULT 'urn:se:customs:datamodel:WCO:Declaration:1') SELECT ExporterAddressLine.value('(.)[1]', 'VARCHAR(100)') AS ExporterAddressLine FROM CustomsDeclarations CROSS APPLY XmlContent.nodes('/Declaration/GoodsShipment/Exporter/Address/Line') AS T(ExporterAddressLine);
关键说明
- 必须显式声明默认命名空间,否则SQL Server会将XPath中的节点视为无命名空间节点,和XML中带命名空间的节点不匹配。
- 你之前去掉
Declaration标签能工作,是因为去掉了默认命名空间的定义,子节点不再属于任何命名空间,查询时无需指定。
内容的提问来源于stack exchange,提问作者Carl
相关产品推荐
相关产品推荐

