在 SQL 服务器中解析 XML (使用数组)
Parse XML in SQL Server (with an array)
我正在尝试解析 SQL 服务器中的一些 XML,我已经开发了一些代码来执行此操作,但是返回的数据项之一以数组的形式出现?
SQL 到目前为止,示例 XML...
DECLARE @XML XML
SET @XML = '<?xml version="1.0" encoding="UTF-8"?>
<feedback-items>
<feedback-item id="1001">
<message>The message</message>
<sentiment-score>3</sentiment-score>
<channel>SMS</channel>
<structured-fields>
<structured-field>
<name>loyalty_card_number</name>
<value>123456</value>
</structured-field>
<structured-field>
<name>given_score</name>
<value>4</value>
</structured-field>
</structured-fields>
<categories>
<category>People</category>
<category>Process</category>
<category>Product</category>
<category>Place</category>
</categories>
<insights>
<insight>
<category>People</category>
<sentiment-score>1</sentiment-score>
</insight>
</insights>
<notes>
<note>
<id>1</id>
<username>Bob</username>
<created>2012-12-11 09:00:00</created>
<content>The customer was happy</content>
</note>
</notes>
</feedback-item>
<feedback-item id="1002">
<message>The message</message>
<sentiment-score>3</sentiment-score>
<channel>SMS</channel>
<structured-fields>
<structured-field>
<name>loyalty_card_number</name>
<value>123456</value>
</structured-field>
<structured-field>
<name>given_score</name>
<value>6</value>
</structured-field>
</structured-fields>
<categories>
<category>People</category>
<category>Process</category>
<category>Product</category>
<category>Place</category>
</categories>
<insights>
<insight>
<category>People</category>
<sentiment-score>1</sentiment-score>
</insight>
</insights>
<notes>
<note>
<id>1</id>
<username>Mike</username>
<created>2012-12-12 09:00:00</created>
<content>The customer was happy</content>
</note>
</notes>
</feedback-item>
</feedback-items>
'
SELECT
xmlData.A.value('@id','INT') AS [FeedbackItem]
--fields.A.value('./Name/text())[1]','Varchar(50)') AS [Name]
--xmlData.A.value('(./structured-fields/structured-field/Name/text())[1]','Varchar(50)') AS [Name]
FROM @XML.nodes('feedback-items/feedback-item') xmlData(A)
--CROSS APPLY xmlData.A.nodes('/structured-fields/structured-field') AS fields(A)
期望的输出...
Feedback Item
Message
Sentiment Score
Channel
Loyalty Card Number
Given Score
Username
Created
Content
1001
The message
3
SMS
123456
6
Bob
2012-12-11
The Customer was happy
1002
The message
3
SMS
123456
4
Mike
2012-12-12
The Customer was happy
请尝试以下解决方案。
您的 XPath 表达式有问题。
SQL
DECLARE @xml XML =
N'<feedback-items>
<feedback-item id="1001">
<message>The message</message>
<sentiment-score>3</sentiment-score>
<channel>SMS</channel>
<structured-fields>
<structured-field>
<name>loyalty_card_number</name>
<value>123456</value>
</structured-field>
<structured-field>
<name>given_score</name>
<value>4</value>
</structured-field>
</structured-fields>
<categories>
<category>People</category>
<category>Process</category>
<category>Product</category>
<category>Place</category>
</categories>
<insights>
<insight>
<category>People</category>
<sentiment-score>1</sentiment-score>
</insight>
</insights>
<notes>
<note>
<id>1</id>
<username>Bob</username>
<created>2012-12-11 09:00:00</created>
<content>The customer was happy</content>
</note>
</notes>
</feedback-item>
<feedback-item id="1002">
<message>The message</message>
<sentiment-score>3</sentiment-score>
<channel>SMS</channel>
<structured-fields>
<structured-field>
<name>loyalty_card_number</name>
<value>123456</value>
</structured-field>
<structured-field>
<name>given_score</name>
<value>6</value>
</structured-field>
</structured-fields>
<categories>
<category>People</category>
<category>Process</category>
<category>Product</category>
<category>Place</category>
</categories>
<insights>
<insight>
<category>People</category>
<sentiment-score>1</sentiment-score>
</insight>
</insights>
<notes>
<note>
<id>1</id>
<username>Mike</username>
<created>2012-12-12 09:00:00</created>
<content>The customer was happy</content>
</note>
</notes>
</feedback-item>
</feedback-items>
';
SELECT a.value('@id','INT') AS [FeedbackItem]
, a.value('(message/text())[1]','Varchar(50)') AS [Message]
, a.value('(sentiment-score/text())[1]','Varchar(50)') AS [SentimentScore]
, a.value('(channel/text())[1]','Varchar(50)') AS [channel]
, a.value('(structured-fields/structured-field[name="loyalty_card_number"]/value/text())[1]','Varchar(50)') AS [loyalty_card_number]
, a.value('(structured-fields/structured-field[name="given_score"]/value/text())[1]','Varchar(50)') AS [GivenScore]
, b.value('(username/text())[1]','Varchar(50)') AS [Username]
, b.value('(created/text())[1]','DATE') AS [created]
, b.value('(content/text())[1]','VARCHAR(100)') AS [content]
FROM @XML.nodes('/feedback-items/feedback-item') t1(a)
CROSS APPLY t1.a.nodes('notes/note') AS t2(b);
输出
+--------------+-------------+----------------+---------+---------------------+------------+----------+------------+------------------------+
| FeedbackItem | Message | SentimentScore | channel | loyalty_card_number | GivenScore | Username | created | content |
+--------------+-------------+----------------+---------+---------------------+------------+----------+------------+------------------------+
| 1001 | The message | 3 | SMS | 123456 | 4 | Bob | 2012-12-11 | The customer was happy |
| 1002 | The message | 3 | SMS | 123456 | 6 | Mike | 2012-12-12 | The customer was happy |
+--------------+-------------+----------------+---------+---------------------+------------+----------+------------+------------------------+
您可以使用以下代码
SELECT
[Feedback Item] = fb.value('@id','int'),
Message = fb.value('(message/text())[1]','nvarchar(200)'),
[Sentiment Score] = fb.value('(sentiment-score/text())[1]','int'),
Channel = fb.value('(channel/text())[1]','nvarchar(200)'),
[Loyalty Card Number] = fb.value('(structured-fields/structured-field[name[text()="loyalty_card_number"]]/value/text())[1]','nvarchar(200)'),
[Given Score] = fb.value('(structured-fields/structured-field[name[text()="given_score"]]/value/text())[1]','nvarchar(200)'),
Username = fb.value('(notes/note/username/text())[1]','nvarchar(200)'),
Created = fb.value('(notes/note/created/text())[1]','datetime'),
Content = fb.value('(notes/note/content/text())[1]','nvarchar(200)')
FROM @xml.nodes('feedback-items/feedback-item') x(fb)
进一步说明:
- XML 被截断了,我向其中添加了一些以获得所需的结果。我假设你有更多。
- 请注意如何在
name/text()
上过滤 structured-field
,然后检索 value/text(0
notes/note
看起来它可能包含多个项目,您可能需要将其与另一个 .nodes
分开
我正在尝试解析 SQL 服务器中的一些 XML,我已经开发了一些代码来执行此操作,但是返回的数据项之一以数组的形式出现?
SQL 到目前为止,示例 XML...
DECLARE @XML XML
SET @XML = '<?xml version="1.0" encoding="UTF-8"?>
<feedback-items>
<feedback-item id="1001">
<message>The message</message>
<sentiment-score>3</sentiment-score>
<channel>SMS</channel>
<structured-fields>
<structured-field>
<name>loyalty_card_number</name>
<value>123456</value>
</structured-field>
<structured-field>
<name>given_score</name>
<value>4</value>
</structured-field>
</structured-fields>
<categories>
<category>People</category>
<category>Process</category>
<category>Product</category>
<category>Place</category>
</categories>
<insights>
<insight>
<category>People</category>
<sentiment-score>1</sentiment-score>
</insight>
</insights>
<notes>
<note>
<id>1</id>
<username>Bob</username>
<created>2012-12-11 09:00:00</created>
<content>The customer was happy</content>
</note>
</notes>
</feedback-item>
<feedback-item id="1002">
<message>The message</message>
<sentiment-score>3</sentiment-score>
<channel>SMS</channel>
<structured-fields>
<structured-field>
<name>loyalty_card_number</name>
<value>123456</value>
</structured-field>
<structured-field>
<name>given_score</name>
<value>6</value>
</structured-field>
</structured-fields>
<categories>
<category>People</category>
<category>Process</category>
<category>Product</category>
<category>Place</category>
</categories>
<insights>
<insight>
<category>People</category>
<sentiment-score>1</sentiment-score>
</insight>
</insights>
<notes>
<note>
<id>1</id>
<username>Mike</username>
<created>2012-12-12 09:00:00</created>
<content>The customer was happy</content>
</note>
</notes>
</feedback-item>
</feedback-items>
'
SELECT
xmlData.A.value('@id','INT') AS [FeedbackItem]
--fields.A.value('./Name/text())[1]','Varchar(50)') AS [Name]
--xmlData.A.value('(./structured-fields/structured-field/Name/text())[1]','Varchar(50)') AS [Name]
FROM @XML.nodes('feedback-items/feedback-item') xmlData(A)
--CROSS APPLY xmlData.A.nodes('/structured-fields/structured-field') AS fields(A)
期望的输出...
Feedback Item | Message | Sentiment Score | Channel | Loyalty Card Number | Given Score | Username | Created | Content |
---|---|---|---|---|---|---|---|---|
1001 | The message | 3 | SMS | 123456 | 6 | Bob | 2012-12-11 | The Customer was happy |
1002 | The message | 3 | SMS | 123456 | 4 | Mike | 2012-12-12 | The Customer was happy |
请尝试以下解决方案。
您的 XPath 表达式有问题。
SQL
DECLARE @xml XML =
N'<feedback-items>
<feedback-item id="1001">
<message>The message</message>
<sentiment-score>3</sentiment-score>
<channel>SMS</channel>
<structured-fields>
<structured-field>
<name>loyalty_card_number</name>
<value>123456</value>
</structured-field>
<structured-field>
<name>given_score</name>
<value>4</value>
</structured-field>
</structured-fields>
<categories>
<category>People</category>
<category>Process</category>
<category>Product</category>
<category>Place</category>
</categories>
<insights>
<insight>
<category>People</category>
<sentiment-score>1</sentiment-score>
</insight>
</insights>
<notes>
<note>
<id>1</id>
<username>Bob</username>
<created>2012-12-11 09:00:00</created>
<content>The customer was happy</content>
</note>
</notes>
</feedback-item>
<feedback-item id="1002">
<message>The message</message>
<sentiment-score>3</sentiment-score>
<channel>SMS</channel>
<structured-fields>
<structured-field>
<name>loyalty_card_number</name>
<value>123456</value>
</structured-field>
<structured-field>
<name>given_score</name>
<value>6</value>
</structured-field>
</structured-fields>
<categories>
<category>People</category>
<category>Process</category>
<category>Product</category>
<category>Place</category>
</categories>
<insights>
<insight>
<category>People</category>
<sentiment-score>1</sentiment-score>
</insight>
</insights>
<notes>
<note>
<id>1</id>
<username>Mike</username>
<created>2012-12-12 09:00:00</created>
<content>The customer was happy</content>
</note>
</notes>
</feedback-item>
</feedback-items>
';
SELECT a.value('@id','INT') AS [FeedbackItem]
, a.value('(message/text())[1]','Varchar(50)') AS [Message]
, a.value('(sentiment-score/text())[1]','Varchar(50)') AS [SentimentScore]
, a.value('(channel/text())[1]','Varchar(50)') AS [channel]
, a.value('(structured-fields/structured-field[name="loyalty_card_number"]/value/text())[1]','Varchar(50)') AS [loyalty_card_number]
, a.value('(structured-fields/structured-field[name="given_score"]/value/text())[1]','Varchar(50)') AS [GivenScore]
, b.value('(username/text())[1]','Varchar(50)') AS [Username]
, b.value('(created/text())[1]','DATE') AS [created]
, b.value('(content/text())[1]','VARCHAR(100)') AS [content]
FROM @XML.nodes('/feedback-items/feedback-item') t1(a)
CROSS APPLY t1.a.nodes('notes/note') AS t2(b);
输出
+--------------+-------------+----------------+---------+---------------------+------------+----------+------------+------------------------+
| FeedbackItem | Message | SentimentScore | channel | loyalty_card_number | GivenScore | Username | created | content |
+--------------+-------------+----------------+---------+---------------------+------------+----------+------------+------------------------+
| 1001 | The message | 3 | SMS | 123456 | 4 | Bob | 2012-12-11 | The customer was happy |
| 1002 | The message | 3 | SMS | 123456 | 6 | Mike | 2012-12-12 | The customer was happy |
+--------------+-------------+----------------+---------+---------------------+------------+----------+------------+------------------------+
您可以使用以下代码
SELECT
[Feedback Item] = fb.value('@id','int'),
Message = fb.value('(message/text())[1]','nvarchar(200)'),
[Sentiment Score] = fb.value('(sentiment-score/text())[1]','int'),
Channel = fb.value('(channel/text())[1]','nvarchar(200)'),
[Loyalty Card Number] = fb.value('(structured-fields/structured-field[name[text()="loyalty_card_number"]]/value/text())[1]','nvarchar(200)'),
[Given Score] = fb.value('(structured-fields/structured-field[name[text()="given_score"]]/value/text())[1]','nvarchar(200)'),
Username = fb.value('(notes/note/username/text())[1]','nvarchar(200)'),
Created = fb.value('(notes/note/created/text())[1]','datetime'),
Content = fb.value('(notes/note/content/text())[1]','nvarchar(200)')
FROM @xml.nodes('feedback-items/feedback-item') x(fb)
进一步说明:
- XML 被截断了,我向其中添加了一些以获得所需的结果。我假设你有更多。
- 请注意如何在
name/text()
上过滤structured-field
,然后检索value/text(0
notes/note
看起来它可能包含多个项目,您可能需要将其与另一个.nodes
分开