sql-server - xmlns 的 XML 提取问题
问题描述
我有一些我试图提取的标准 XML 代码,我已经阅读了关于 xmlns 的各种不同的问题,并且我的代码到此为止,但我似乎无法做的是提取“ " 代表客户 ID -
DECLARE @docHandle INT
DECLARE @XmlDocument NVARCHAR(1000)
DECLARE @rootxmlns VARCHAR(1000)
SET @XmlDocument ='
<Root xmlns="http://www.adventure-works.com">
<Customers>
<Customer CustomerID="GREAL">
<CompanyName>Great Lakes Food Market</CompanyName>
<ContactName>Howard Snyder</ContactName>
<ContactTitle>Marketing Manager</ContactTitle>
<Phone>(503) 555-7555</Phone>
</Customer>
</Customers>
</Root> '
SET @rootxmlns = '<Root xmlns:hm="http://www.adventure-works.com"/>'
-- Create an internal representation of the XML document.
EXEC Sp_xml_preparedocument
@docHandle output,
@XmlDocument,
@rootxmlns
-- Execute a SELECT statement using OPENXML rowset provider.
SELECT *
FROM OPENXML (@docHandle, '/hm:Root/hm:Customers', 3)
WITH ([CustomerID] CHAR(10) './hm:CustomerID'
,[Customer.CompanyName] VARCHAR(100)'hm:Customer/hm:CompanyName'
,[Customer.ContactName] VARCHAR(100)
'hm:Customer/hm:ContactName' )
EXEC Sp_xml_removedocument
@docHandle
解决方案
您与FROM OPENXML
存储过程一起创建和删除 XML 文档的方法已经过时,不应再使用。更好、更快、更容易阅读的是原生 XML 方法(其中一些自 v2005 起受支持)。
我将您的 XML 放在本地声明的变量中。但是您可以将此方法内联到针对表数据的任何查询中,这允许在 VIEW 和 iTVF 中使用 XML。
DECLARE @XmlDocument XML;
SET @XmlDocument ='
<Root xmlns="http://www.adventure-works.com">
<Customers>
<Customer CustomerID="GREAL">
<CompanyName>Great Lakes Food Market</CompanyName>
<ContactName>Howard Snyder</ContactName>
<ContactTitle>Marketing Manager</ContactTitle>
<Phone>(503) 555-7555</Phone>
</Customer>
</Customers>
</Root>';
--首先我们声明默认命名空间(xmlns="Some URI"
)
WITH XMLNAMESPACES(DEFAULT 'http://www.adventure-works.com')
SELECT c.value('(Customer/@CustomerID)[1]','nvarchar(max)') AS CustomerID
,c.value('(Customer/CompanyName/text())[1]','nvarchar(max)') AS CompanyName
,c.value('(Customer/ContactName/text())[1]','nvarchar(max)') AS ContactName
,c.value('(Customer/ContactTitle/text())[1]','nvarchar(max)') AS ContactTitle
,c.value('(Customer/Phone/text())[1]','nvarchar(max)') AS Phone
FROM @XmlDocument.nodes('/Root/Customers') A(c)
从<Customers>
我假设的复数形式来看,一个 XML 中可能有多个客户。这就是为什么我使用.nodes()
它来获取包含所有客户的派生表(将按每个客户的行方式返回)。
-.value()
方法将读取第二个参数中提供的特定类型的值。