从SQL XML字段中提取值

时间:2011-01-31 20:01:50

标签: sql sql-server xml xpath

使用MS SQL Server,我在XML字段中有一些数据(称为 XML ),其结构如下:

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

我正在尝试创建一个SQL查询来获取另一个名为SubmittedDate的列,以及来自此XML字段的PO_NBR。作为XPath的新手,我已经阅读了大量示例并尝试了查询,但我还没有成功。例如:

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 个答案:

答案 0 :(得分:4)

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 :(得分:1)

如果你想避免硬编码Transaction01,你可以试试这个:

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

E.G:

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
相关问题