简体   繁体   English

T-SQL XML从节点问题中获取值?

[英]T-SQL XML get a value from a node problem?

I have an XML like: 我有一个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>

I'm trying to get the CPProjectId as a Uniqueidentifier using: 我正在尝试使用以下方法将CPProjectId作为Uniqueidentifier:

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

All i can receive is NULL =/ I've tried many combinations on @myDoc.value but no results =/ 我只能收到的是NULL = /我在@ myDoc.value上尝试了很多组合,但没有结果= /

How can i retrieve the value from my XML ? 如何从XML中检索值?

Thanks! 谢谢!

--EDIT: Something that i noted, when i remove the namespace declaration from the XML it works fine! --EDIT:我注意到的东西,当我从XML中删除命名空间声明时,它工作正常! The problem is that i need this namespaces! 问题是我需要这个命名空间! =/ = /

You're right the namespace is the issue. 你是对的,命名空间就是问题所在。 You're query is looking for a node ExportProjectDetailsMessage but such a node doesn't exist in your document, because there is a namespace declared as a default in your document. 您正在查询节点ExportProjectDetailsMessage,但您的文档中不存在此类节点,因为在文档中声明了一个名称空间。 Since you can't remove that (nor should you) you should include it in your XPATH query like so: 既然你不能删除它(你也不应该),你应该将它包含在XPATH查询中,如下所示:

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

You may also want to consider not using varchar(max) but perhaps uniqueidentifier 您可能还想考虑不使用varchar(max),但可能考虑使用uniqueidentifier

A better way to do this is to simply declare the namespace before each of your queries: 更好的方法是在每个查询之前简单地声明命名空间:

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

It's like a temporary default. 这就像是临时违约。 When you run the next query in the batch you'll get nulls again if you don't specify this before each of your selects. 当您在批处理中运行下一个查询时,如果在每个选择之前未指定此参数,则将再次获得空值。

So instead of using "SET", you can use "SELECT" to set the value like so: 因此,您可以使用“SELECT”来设置值,而不是使用“SET”:

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

Same results, just more readable and maintainable. 相同的结果,更具可读性和可维护性。 I found the solution here: http://www.sqlservercentral.com/Forums/Topic967100-145-1.aspx#bm967325 我在这里找到了解决方案: http//www.sqlservercentral.com/Forums/Topic967100-145-1.aspx#bm967325

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM