我正在尝试从下面的XML中以表格格式提取值。
它最初存储为十六进制,但已成功转换,现在需要以表格格式从中提取所有值。
例如一个ROW
BID 2
来自
<ns2:e k="BID">
<ns2:l v="2"/>
</ns2:e>
以此类推。
<ns2:pay xmlns:ns2="http://someurl.com/">
<ns2:e k="BID">
<ns2:l v="2"/>
</ns2:e>
<ns2:e k="PMD">
<ns2:l v="1"/>
</ns2:e>
<ns2:e k="GPTA5">
<ns2:s v=""/>
</ns2:e>
<ns2:e k="GPTA4">
<ns2:s v=""/>
</ns2:e>
<ns2:e k="GPTA3">
<ns2:s v="572"/>
</ns2:e>
<ns2:e k="GPTA1">
<ns2:s v="Sweet & Sour Sauce"/>
</ns2:e>
<ns2:e k="PFID">
<ns2:l v="1"/>
</ns2:e>
<ns2:e k="EAN">
<ns2:s v="010000"/>
</ns2:e>
<ns2:e k="PT">
<ns2:s v="1"/>
</ns2:eBID>
<ns2:e k="TXID1">
<ns2:l v="0"/>
</ns2:e>
<ns2:e k="PMN">
<ns2:l v="1"/>
</ns2:e>
<ns2:e k="DID">
<ns2:l v="1"/>
</ns2:e>
<ns2:e k="GPTA6">
<ns2:s v=""/>
</ns2:e>
<ns2:e k="GPTA7">
<ns2:s v=""/>
</ns2:e>
<ns2:e k="PLU">
<ns2:l v="10000"/>
</ns2:e>
<ns2:e k="GPTA8">
<ns2:s v=""/>
</ns2:e>
<ns2:e k="DYT">
<ns2:s v="SWEET & SOUR SAUCE"/>
</ns2:e>
</ns2:payload>
任何帮助都将不胜感激。
答案 0 :(得分:1)
由于提供的示例格式不正确,我不得不修复您的XML。因此,您可能需要对此进行调整。
DECLARE @xml XML=
N'<ns2:pay xmlns:ns2="http://someurl.com/">
<ns2:e k="BID">
<ns2:l v="2"/>
</ns2:e>
<ns2:e k="PMD">
<ns2:l v="1"/>
</ns2:e>
<ns2:e k="GPTA5">
<ns2:s v=""/>
</ns2:e>
<ns2:e k="GPTA4">
<ns2:s v=""/>
</ns2:e>
<ns2:e k="GPTA3">
<ns2:s v="572"/>
</ns2:e>
<ns2:e k="GPTA1">
<ns2:s v="Sweet & Sour Sauce"/>
</ns2:e>
<ns2:e k="PFID">
<ns2:l v="1"/>
</ns2:e>
<ns2:e k="EAN">
<ns2:s v="010000"/>
</ns2:e>
<ns2:e k="PT">
<ns2:s v="1"/>
</ns2:e>
<ns2:e k="TXID1">
<ns2:l v="0"/>
</ns2:e>
<ns2:e k="PMN">
<ns2:l v="1"/>
</ns2:e>
<ns2:e k="DID">
<ns2:l v="1"/>
</ns2:e>
<ns2:e k="GPTA6">
<ns2:s v=""/>
</ns2:e>
<ns2:e k="GPTA7">
<ns2:s v=""/>
</ns2:e>
<ns2:e k="PLU">
<ns2:l v="10000"/>
</ns2:e>
<ns2:e k="GPTA8">
<ns2:s v=""/>
</ns2:e>
<ns2:e k="DYT">
<ns2:s v="SWEET & SOUR SAUCE"/>
</ns2:e>
</ns2:pay>';
-此查询将返回所有属性及其名称(经典键值列表)
WITH XMLNAMESPACES('http://someurl.com/' AS ns2)
SELECT e.value('@k','nvarchar(max)') AS AttributeName
,e.value('(ns2:l/@v)[1]','nvarchar(max)') AS AttributeValue
FROM @xml.nodes(N'/ns2:pay/ns2:e') A(e);
-此查询使您可以选择一个给定键的值
DECLARE @FindThis NVARCHAR(100)='BID';
WITH XMLNAMESPACES('http://someurl.com/' AS ns2)
SELECT @xml.value(N'(/ns2:pay/ns2:e[@k=sql:variable("@FindThis")]/ns2:l/@v)[1]','int'); --use the proper type, if all values will be fine with this
-此查询将返回一个值表(只要您事先知道所有键)
WITH XMLNAMESPACES('http://someurl.com/' AS ns2)
SELECT @xml.value(N'(/ns2:pay/ns2:e[@k="BID"]/ns2:l/@v)[1]','int') AS BID
,@xml.value(N'(/ns2:pay/ns2:e[@k="PMD"]/ns2:l/@v)[1]','nvarchar(max)') AS PMD
,@xml.value(N'(/ns2:pay/ns2:e[@k="GPTA4"]/ns2:l/@v)[1]','nvarchar(max)') AS GPTA4
--add all keys in the same way...
下面是一个示例,该示例使用PIVOT
从表中读取,以表格形式显示:
提示:我使用NVARCHAR(1000)
模拟您对cast
即时运行的需求:
DECLARE @mockupTable TABLE(ID INT,YourData NVARCHAR(1000));
INSERT INTO @mockupTable VALUES
(1
,N'<ns2:pay xmlns:ns2="http://someurl.com/">
<ns2:e k="BID">
<ns2:l v="2"/>
</ns2:e>
<ns2:e k="PMD">
<ns2:l v="1"/>
</ns2:e>
<ns2:e k="GPTA5">
<ns2:s v=""/>
</ns2:e>
<ns2:e k="GPTA4">
<ns2:s v=""/>
</ns2:e>
<ns2:e k="GPTA3">
<ns2:s v="572"/>
</ns2:e>
<!--shortened for brevity-->
</ns2:pay>')
,(2
,N'<ns2:pay xmlns:ns2="http://someurl.com/">
<ns2:e k="BID">
<ns2:l v="20"/>
</ns2:e>
<ns2:e k="PMD">
<ns2:l v="10"/>
</ns2:e>
<ns2:e k="GPTA5">
<ns2:s v="bla"/>
</ns2:e>
<ns2:e k="GPTA4">
<ns2:s v=""/>
</ns2:e>
<ns2:e k="GPTA3">
<ns2:s v="572"/>
</ns2:e>
<!--shortened for brevity-->
</ns2:pay>');
-查询将创建一个键值列表,并将行的ID作为分组因子
WITH XMLNAMESPACES('http://someurl.com/' AS ns2)
SELECT p.*
FROM
(
SELECT ID
,e.value('@k','nvarchar(max)') AS AttributeName
,e.value('(ns2:l/@v)[1]','nvarchar(max)') AS AttributeValue
FROM @mockupTable t
--the cast happens here
CROSS APPLY(SELECT CAST(t.YourData AS XML)) A(TheXml)
--the call to .nodes() happens here to return a derived table
CROSS APPLY TheXml.nodes(N'/ns2:pay/ns2:e') B(e)
) tbl
PIVOT(MAX(AttributeValue)
FOR AttributeName
IN(BID,PMD,GPTA3,GPTA4,GPTA5) --add your columns here, order does not matter
) p