Извлечь значение из поля SQL XML - PullRequest
3 голосов
/ 31 января 2011

Используя MS SQL Server, у меня есть некоторые данные в поле XML (называемое XML ), которое имеет следующую структуру:

<Transaction01>
  <TransactionSetPurpose>Insert</TransactionSetPurpose>
  <POHeader>
    <PO_NBR>LG40016181</PO_NBR>
  </POHeader>
</Transaction01>

Я пытаюсь создатьSQL-запрос для извлечения другого столбца с именем SubmittedDate вместе с PO_NBR из этого поля XML.Будучи новичком в XPath, я прочитал множество примеров и попробовал оба query и value , но я пока не добился успеха.Например:

SELECT SubmittedDate, 
       XML.query('data(/POHeader/PO_NBR)') as PO_NBR
  FROM SubmitXML

Это просто дает мне пустой столбец.Получив рабочий тест от Quassnoi, я перешел с его XML на мой и обнаружил, что проблема заключается в атрибутах xmlns и xmlns: i в корневом узле:

<Transaction01 xmlns="http://services.iesltd.com/" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">

Так как мне обойти это?

Ответы [ 2 ]

4 голосов
/ 31 января 2011
SELECT  SubmittedDate, 
        XML.query('data(/Transaction01/POHeader/PO_NBR)') as PO_NBR
FROM    SubmitXML

Вы изначально XPath, /POHeader/PO_NBR, предположили, что POHeader является корневым узлом (а не).

Пример запроса для проверки:

DECLARE @myxml XML
SET @myxml = '
<Transaction01>
  <TransactionSetPurpose>Insert</TransactionSetPurpose>
  <POHeader>
    <PO_NBR>LG40016181</PO_NBR>
  </POHeader>
</Transaction01>'

SELECT  @myxml.query('data(/Transaction01/POHeader/PO_NBR)')

Если Transaction01 не всегда является корневым узлом (что не очень хорошо), используйте это:

SELECT  SubmittedDate, 
        XML.query('data(/*/POHeader/PO_NBR)') as PO_NBR
FROM    SubmitXML

Как правило, схема XML предполагает, что имена тегов фиксированы, а переменные частиперейти к данным узлов и атрибутов, а не к их именам, например:

<Transaction id='01'>
  <TransactionSetPurpose>Insert</TransactionSetPurpose>
  <POHeader>
    <PO_NBR>LG40016181</PO_NBR>
  </POHeader>
</Transaction>

Обновление:

Вы должны объявить пространства имен с помощью WITH XMLNAMESPACES:

DECLARE @myxml XML
SET @myxml = '
<Transaction01 xmlns="http://services.iesltd.com/" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <TransactionSetPurpose>Insert</TransactionSetPurpose>
  <POHeader>
    <PO_NBR>LG40016181</PO_NBR>
  </POHeader>
</Transaction01>'

;
WITH    XMLNAMESPACES
        (
        'http://services.iesltd.com/' AS m
        )
SELECT  @myxml.query
        (
        'data(/*/m:POHeader/m:PO_NBR)'
        )

Обновление 2:

Сортировка:

;
WITH    XMLNAMESPACES
        (
        'http://services.iesltd.com/' AS m
        )
SELECT  SubmittedDate, 
        XML.value('(/*/m:POHeader/m:PO_NBR)[1]', 'NVARCHAR(200)') AS po_nbr
FROM    SubmitXML
ORDER BY
        po_nbr
1 голос
/ 31 января 2011

Если вы хотите избежать жесткого кодирования Transaction01, вы можете попробовать это:

SELECT  SubmittedDate,          
        XML.query('data(//POHeader/PO_NBR)') as PO_NBR 
  FROM  SubmitXML 

EG:

CREATE TABLE #TEMP (XMLTEXT XML)

INSERT INTO #TEMP 
SELECT '<Transaction01>   <TransactionSetPurpose>Insert</TransactionSetPurpose>   <POHeader>     <PO_NBR>LG40016181</PO_NBR>   </POHeader> </Transaction01> '

SELECT XMLTEXT.query('data(//POHeader/PO_NBR)') as PO_NBR   
 FROM #TEMP
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...