2011-08-05 37 views
6

我有一个XML这样的:T-SQL XML从节点问题中获取值?

<?xml version="1.0" encoding="utf-16"?> 
<ExportProjectDetailsMessage xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Project"> 
<CPProjectId>7665699f-6772-424c-8b7b-405b9220a8e7</CPProjectId> 
</ExportProjectDetailsMessage> 

我试图使用获得CPProjectId作为唯一标识符:

DECLARE @myDoc xml 
DECLARE @ProdID varchar(max) 

SET @myDoc = '<ExportProjectDetailsMessage xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Project"><CPProjectId>7665699f-6772-424c-8b7b-405b9220a8e7</CPProjectId></ExportProjectDetailsMessage>' 

SET @ProdID = @myDoc.value('(ExportProjectDetailsMessage/CPProjectId)[1]', 'varchar(max)') 
SELECT @ProdID 

所有我能够接收到NULL =/ 我试过很多的组合on @ myDoc.value但没有结果=/

如何从我的XML中检索值?

谢谢!

- EDIT: 我注意到,当我从XML中删除名称空间声明它工作正常! 问题是我需要这个命名空间! =/

+0

请参阅:http://stackoverflow.com/questions/4081906/sql-server-xml-namespace-querying-problem技巧是“WITH NAMESPACES”,然后使用“ns:”形成。 – 2011-08-05 20:46:37

回答

4

你是对的命名空间是问题。您正在查询的是查找节点ExportProjectDetailsMessage,但这样的节点不存在于您的文档中,因为在您的文档中声明了一个默认名称空间。既然你无法删除(也不应该知道),你应该包括在你的XPath查询,像这样:

set @ProdId = @myDoc.value(' 
    declare namespace PD="http://schemas.datacontract.org/2004/07/Project";   
(PD:ExportProjectDetailsMessage/PD:CPProjectId)[1]', 'varchar(max)') 

您也可以考虑不使用VARCHAR(最大值),但也许是唯一标识符

+0

男人..很多谢谢! ;)PS:我正在使用varchar仅用于其他字段的测试=] – renanlf

1

一更好的方式来做到这一点是每个查询的前简单地声明命名空间:

;WITH XMLNAMESPACES(DEFAULT 'http://schemas.datacontract.org/2004/07/Project') 

它就像一个临时的默认。当您在批处理中运行下一个查询时,如果您未在每次选择之前指定此值,则会再次得到空值。

因此,而不是使用“SET”,可以用“选择”设置值,像这样:

;WITH XMLNAMESPACES(DEFAULT 'http://schemas.datacontract.org/2004/07/Project') 
SELECT @ProdID = @myDoc.value('(ExportProjectDetailsMessage/CPProjectId)[1]', 'VarChar(MAX)') 
SELECT @ProdID 

同样的结果,只是更具可读性和可维护性。 我在这里找到了解决方案:http://www.sqlservercentral.com/Forums/Topic967100-145-1.aspx#bm967325

+1

我看到第一个答案在此响应之前被接受。但是对于它的价值,我发现这是一个更好的技术(假设你可以依赖名称空间是一致的)。 – cBlaine