2017-02-14 4 views
4

Я новый XML, но не SQL. У меня есть данные, структурированные нашим приложением поставщика, как следует, что я пытаюсь загрузить в таблицу:XML-значение, погребенное внутри узла

<windowsets> 
    <windows> 
    <question> 
     <id Value="81b25d-9385-sk3" /> 
     <displayname Value="Thermal Break" /> 
     <answername Value="Yes" />  
    </question> 
    <question> 
     <id Value="73v32k-2743-fd9" /> 
     <displayname Value="Panel Profile" /> 
     <answername Value="Medium Stille" />  
    </question> 
    </windows> 
</windowsets> 

Через другие посты здесь я нашел и дошел до создания:

select 
    t.x.value('(id [@Value]/text())[1]','varchar(100)') QuestionID, 
    t.x.value('(displayname [@Value]/text())[1]','varchar(255)') DisplayName, 
    t.x.value('(answername [@Value]/text())[1]','varchar(255)') AnswerName 
from @xmlData.nodes('//windowsets/windows/question') as T(X) 

Но она возвращает аннулирует для всех столбцов, и я предполагаю, что это потому, что он ожидает формат:

<displayname>Panel Profile</displayname> 

Так быть XML послушником и весь поиск я делал, не помогает мне понять, как изменить Колорадо de, чтобы вытащить его, когда значение захоронено в узле (даже не уверен в правильной терминологии, я так новичок).

СПАСИБО за вашу помощь!

+0

кстати: Это хороший вопрос. +1 с моей стороны – Shnugo

ответ

3

Это называется attributes.

Чтобы прочитать attributes из xml попробовать что-то вроде этого

select 
    t.x.value('(id/@Value)[1]','varchar(100)') QuestionID, 
    t.x.value('(displayname/@Value)[1]','varchar(255)') DisplayName, 
    t.x.value('(answername/@Value)[1]','varchar(255)') AnswerName 
from @xmlData.nodes('//windowsets/windows/question') as T(X) 
+0

Все отлично, +1 с моей стороны. Просто крошечный намек: нужно избегать двойной косой черты (* глубокий поиск *), если это не нужно. В этом случае это не будет иметь никакого значения, но в других случаях это может привести к глупым ошибкам ... – Shnugo

+0

Большое спасибо за код и терминологию. Это работало как чемпион! – AKenn

1

Это не новый ответ, просто какое-то объяснение и много для комментария:

Часть в квадратных скобках называется предикат и является своего рода фильтром. Ваше выражение

displayname [@Value]/text())[1] 

будет читать text() из <displayname> и будет проверять, если атрибут @Value существует. Во всяком случае, текст элемента отсутствует, поэтому он вернет NULL.

Вы должны переместиться вниз по пути, как .../displayname/@Value, если вы хотите прочитать значение атрибута.

This answer показывает несколько примеров того, как XML имеет дело с пустыми членами.