T-SQL XML получить значение из проблемы узла? - PullRequest
6 голосов
/ 06 августа 2011

У меня есть 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 = / Я пробовал много комбинаций на @ myDoc.value, но без результатов = /

Как я могу получить значение из моего XML?

Спасибо!

- EDIT: Кое-что, что я заметил, когда я удаляю объявление пространства имен из XML, это работает отлично! Проблема в том, что мне нужно это пространство имен! = /

Ответы [ 2 ]

4 голосов
/ 06 августа 2011

Вы правы, проблема заключается в пространстве имен.Ваш запрос ищет узел ExportProjectDetailsMessage, но такого узла нет в вашем документе, поскольку в вашем документе есть пространство имен, объявленное по умолчанию.Поскольку вы не можете удалить это (и не должны), вы должны включить его в свой запрос XPATH следующим образом:

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

Вы также можете рассмотреть возможность использования не varchar (max), а, возможно, uniqueidentifier

1 голос
/ 02 марта 2012

Лучший способ сделать это - просто объявить пространство имен перед каждым вашим запросом:

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

Это как временный дефолт. Когда вы выполните следующий запрос в пакете, вы снова получите пустые значения, если вы не укажете это перед каждым выбором.

Таким образом, вместо использования «SET», вы можете использовать «SELECT» для установки значения следующим образом:

;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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...