[英]how to extract data from xml having multiple nodes which are same under a parent node into a table in sql
[英]How to extract data from xml node in SQL
下面是我的xml,它記錄在數據庫表中。
<root>
<pagelocation>
<nodeid>3178</nodeid>
<webpart id="editabletextdescriptio2;b5518b76-9fe6-47d2-8d8b-4ab169d3a127">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse non nisl lacus. Donec in rutrum lorem, consectetur semper nunc.
</webpart>
</pagelocation>
<pagelocation>
<NodeId>3180</NodeId>
<webpart id="editabletexttitle;a36d4858-5d61-49b6-a860-221ad0b72310">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse non nisl lacus. Donec in rutrum lorem, consectetur semper nunc.
</webpart>
<webpart id="editabletextdescriptio1;f4873da3-bf3b-43d3-9dc6-cdabfa8c7b6d">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse non nisl lacus. Donec in rutrum lorem, consectetur semper nunc.
</webpart>
<webpart id="editabletextdescriptio2;b5518b76-9fe6-47d2-8d8b-4ab169d3a127">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse non nisl lacus. Donec in rutrum lorem, consectetur semper nunc.
</webpart>
</pagelocation>
</root>
我只需要獲取屬於<webpart id="editabletextdescriptio1;f4873da3-bf3b-43d3-9dc6-cdabfa8c7b6d">
如何在SQL中編寫類似這樣的查詢
如果我找對你(你的“唯一”不清楚),這是一個例子:
DECLARE @xml XML = '
<root>
<pagelocation>
<nodeid>3178</nodeid>
<webpart id="editabletextdescriptio2;b5518b76-9fe6-47d2-8d8b-4ab169d3a127">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse non nisl lacus. Donec in rutrum lorem, consectetur semper nunc.
</webpart>
</pagelocation>
<pagelocation>
<nodeid>3180</nodeid>
<webpart id="editabletexttitle;a36d4858-5d61-49b6-a860-221ad0b72310">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse non nisl lacus. Donec in rutrum lorem, consectetur semper nunc.
</webpart>
<webpart id="editabletextdescriptio1;f4873da3-bf3b-43d3-9dc6-cdabfa8c7b6d">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse non nisl lacus. Donec in rutrum lorem, consectetur semper nunc.
</webpart>
<webpart id="editabletextdescriptio2;b5518b76-9fe6-47d2-8d8b-4ab169d3a127">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse non nisl lacus. Donec in rutrum lorem, consectetur semper nunc.
</webpart>
</pagelocation>
</root>'
SELECT n.c.value('@id', 'nvarchar(max)') FROM
@xml.nodes('/root/pagelocation/webpart') AS n(c)
輸出:
editabletextdescriptio2;b5518b76-9fe6-47d2-8d8b-4ab169d3a127
editabletexttitle;a36d4858-5d61-49b6-a860-221ad0b72310
editabletextdescriptio1;f4873da3-bf3b-43d3-9dc6-cdabfa8c7b6d
editabletextdescriptio2;b5518b76-9fe6-47d2-8d8b-4ab169d3a127
這使用XPath表達式查找具有特定ID的節點。 這使用SQL Server中的nodes()
函數, CROSS APPLY
將其應用於表中的XML,並使用value()
函數進行選擇。
如果您不清楚它是如何工作的:研究XPath表達式,SQL Server中的XPath / XQuery功能和CROSS APPLY
。
DECLARE @t TABLE(x XML);
INSERT INTO @t(x)VALUES('<root>
<pagelocation>
<nodeid>3178</nodeid>
<webpart id="editabletextdescriptio2;b5518b76-9fe6-47d2-8d8b-4ab169d3a127">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse non nisl lacus. Donec in rutrum lorem, consectetur semper nunc.
</webpart>
</pagelocation>
<pagelocation>
<NodeId>3180</NodeId>
<webpart id="editabletexttitle;a36d4858-5d61-49b6-a860-221ad0b72310">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse non nisl lacus. Donec in rutrum lorem, consectetur semper nunc.
</webpart>
<webpart id="editabletextdescriptio1;f4873da3-bf3b-43d3-9dc6-cdabfa8c7b6d">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse non nisl lacus. Donec in rutrum lorem, consectetur semper nunc.
</webpart>
<webpart id="editabletextdescriptio2;b5518b76-9fe6-47d2-8d8b-4ab169d3a127">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse non nisl lacus. Donec in rutrum lorem, consectetur semper nunc.
</webpart>
</pagelocation>
</root>');
SELECT
n.v.value('.','NVARCHAR(256)')
FROM
@t AS t
CROSS APPLY t.x.nodes('//webpart[@id="editabletextdescriptio1;f4873da3-bf3b-43d3-9dc6-cdabfa8c7b6d"]') AS n(v);
我理解如下:
<webpart>
節點 @id
是唯一的 webpart
元素 以下代碼將在聲明的表中插入三行,模擬三種不同的情況。
DECLARE @tbl TABLE(ID INT IDENTITY,Descritpion VARCHAR(100),XmlColumn XML);
INSERT INTO @tbl VALUES
('Contains the Id'
,N'<root>
<pagelocation>
<NodeId>3180</NodeId>
<webpart id="editabletextdescriptio1;f4873da3-bf3b-43d3-9dc6-cdabfa8c7b6d">
Some Content
</webpart>
</pagelocation>
</root>')
,('Does not contain the Id'
,N'<root>
<pagelocation>
<nodeid>3178</nodeid>
<webpart id="editabletextdescriptio2;b5518b76-9fe6-47d2-8d8b-4ab169d3a127">
Other Content
</webpart>
</pagelocation>
</root>')
,('Multiple IDs, one of them fitting'
,N'<root>
<pagelocation>
<nodeid>3178</nodeid>
<webpart id="editabletextdescriptio2;b5518b76-9fe6-47d2-8d8b-4ab169d3a127">
id is not correct
</webpart>
</pagelocation>
<pagelocation>
<NodeId>3180</NodeId>
<webpart id="editabletexttitle;a36d4858-5d61-49b6-a860-221ad0b72310">
Same here
</webpart>
<webpart id="editabletextdescriptio1;f4873da3-bf3b-43d3-9dc6-cdabfa8c7b6d">
Yeah! that is is
</webpart>
<webpart id="editabletextdescriptio2;b5518b76-9fe6-47d2-8d8b-4ab169d3a127">
One more
</webpart>
</pagelocation>
</root>')
- 您要搜索的ID可以定義為參數
DECLARE @SearchFor NVARCHAR(100)=N'editabletextdescriptio1;f4873da3-bf3b-43d3-9dc6-cdabfa8c7b6d';
- 該命令首先使用.query()
來獲取正確的節點,而不是.value
來獲取文本內容
SELECT *
,XmlColumn.query('//webpart[@id=sql:variable("@SearchFor")]').value('.','nvarchar(max)') AS Content
FROM @tbl;
- 這個命令直接在.value()
使用XQuery
(更快,在第一次出現時停止)
SELECT *
,XmlColumn.value('(//webpart[@id=sql:variable("@SearchFor")])[1]','nvarchar(max)') AS Content
FROM @tbl
可以使用CROSS APPLY .nodes()
(就像在其他答案中一樣),但是 - 如果你a)不要指望多行,或者b)想要從一個位置讀取不同的值,它就是一種開銷...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.