使用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">
那么我该如何解决这个问题?
答案 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