我有一个我试图解析成数据库表的Xml文件。
我有一些代码可以做到这一点..但它没有适当地将代码组织到表中,因为它返回所有产品和房间而没有任何订单。
从下面可以看到,xml首先定义房间名称和RoomId。
接下来是该房间的产品清单。 这些产品都存储在表格中,并已分配父级和子级ID。
然后,XML为不同的房间重复此结构。
我已经采用了一些代码,因为有很多样式和不必要的代码。
我想要的是一个可以正确存储此数据的查询,以便我可以将其存储在数据库中,然后在“SQL Server报告”构建器中检索它。
欢呼声
XML
命名空间
<t:RadDocument xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:t="clr-namespace:Telerik.Windows.Documents.Model;assembly=Telerik.Windows.Documents"
xmlns:s="clr-namespace:Telerik.Windows.Documents.Model.Styles;assembly=Telerik.Windows.Documents"
xmlns:r="clr-namespace:Telerik.Windows.Documents.Model.Revisions;assembly=Telerik.Windows.Documents"
xmlns:n="clr-namespace:Telerik.Windows.Documents.Model.Notes;assembly=Telerik.Windows.Documents" xmlns:th="clr-namespace:Telerik.Windows.Documents.Model.Themes;assembly=Telerik.Windows.Documents"
xmlns:custom1="clr-namespace:TAS2;assembly=RadRichTextBoxExtensions"
xmlns:custom2="clr-namespace:;assembly=RadRichTextBoxExtensions" version="1.2" LayoutMode="Paged" LineSpacing="1" LineSpacingType="Auto" ParagraphDefaultSpacingAfter="30" ParagraphDefaultSpacingBefore="30" SelectedBibliographicStyleName="\APA.XSL" StyleName="defaultDocumentStyle">
XML代码段
<custom1:RoomGroupRangeStart RoomID="26" RoomName="Bathroom" />
<custom1:SemanticRangeStart.Product>
<t:Products HasChild="True" ID="48" Level="1" Name="Plumbing" ParentID="1"/>
</custom1:SemanticRangeStart.Product>
<custom1:SemanticRangeStart.Product>
<t:Products HasChild="True" ID="49" Level="2" Name="Central Heating" ParentID="48" />
</custom1:SemanticRangeStart.Product>
<custom1:SemanticRangeStart.Product>
<t:Products HasChild="True" ID="50" Level="3" Name="Gas" ParentID="49" />
</custom1:SemanticRangeStart.Product>
首次尝试
select
nodes.node.value( '@ID', 'int' ) Id,
nodes.node.value( '@Name', 'varchar(max)' ) Name,
nodes.node.value( '@ParentID', 'int' ) ParentId
from
@xml.nodes( '//*:Products' ) nodes ( node )
select
nodes.node.value ( '@RoomID', 'int' ) RoomID,
nodes.node.value ( '@RoomName', 'varchar(max)' ) RoomName
from
@xml.nodes( '//*:RoomGroupRangeStart' ) nodes ( node )
答案 0 :(得分:1)
试试这样:
我添加了一个带有虚拟命名空间的根节点和几个重复的结构......
DECLARE @x XML=
'<t:RadDocument xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:t="clr-namespace:Telerik.Windows.Documents.Model;assembly=Telerik.Windows.Documents"
xmlns:s="clr-namespace:Telerik.Windows.Documents.Model.Styles;assembly=Telerik.Windows.Documents"
xmlns:r="clr-namespace:Telerik.Windows.Documents.Model.Revisions;assembly=Telerik.Windows.Documents"
xmlns:n="clr-namespace:Telerik.Windows.Documents.Model.Notes;assembly=Telerik.Windows.Documents" xmlns:th="clr-namespace:Telerik.Windows.Documents.Model.Themes;assembly=Telerik.Windows.Documents"
xmlns:custom1="clr-namespace:TAS2;assembly=RadRichTextBoxExtensions"
xmlns:custom2="clr-namespace:;assembly=RadRichTextBoxExtensions" version="1.2" LayoutMode="Paged" LineSpacing="1" LineSpacingType="Auto" ParagraphDefaultSpacingAfter="30" ParagraphDefaultSpacingBefore="30" SelectedBibliographicStyleName="\APA.XSL" StyleName="defaultDocumentStyle">
<custom1:RoomGroupRangeStart RoomID="26" RoomName="Bathroom" />
<custom1:SemanticRangeStart.Product>
<t:Products HasChild="True" ID="48" Level="1" Name="Plumbing" ParentID="1" />
</custom1:SemanticRangeStart.Product>
<custom1:SemanticRangeStart.Product>
<t:Products HasChild="True" ID="49" Level="2" Name="Central Heating" ParentID="48" />
</custom1:SemanticRangeStart.Product>
<custom1:SemanticRangeStart.Product>
<t:Products HasChild="True" ID="50" Level="3" Name="Gas" ParentID="49" />
</custom1:SemanticRangeStart.Product>
<custom1:RoomGroupRangeStart RoomID="27" RoomName="Test" />
<custom1:SemanticRangeStart.Product>
<t:Products HasChild="True" ID="48" Level="1" Name="Test1" ParentID="1" />
</custom1:SemanticRangeStart.Product>
<custom1:SemanticRangeStart.Product>
<t:Products HasChild="True" ID="49" Level="2" Name="Test2" ParentID="48" />
</custom1:SemanticRangeStart.Product>
<custom1:SemanticRangeStart.Product>
<t:Products HasChild="True" ID="50" Level="3" Name="Test3" ParentID="49" />
</custom1:SemanticRangeStart.Product>
<custom1:RoomGroupRangeStart RoomID="28" RoomName="OneMore" />
<custom1:SemanticRangeStart.Product>
<t:Products HasChild="True" ID="48" Level="1" Name="OneMore1" ParentID="1" />
</custom1:SemanticRangeStart.Product>
<custom1:SemanticRangeStart.Product>
<t:Products HasChild="True" ID="49" Level="2" Name="OneMore2" ParentID="48" />
</custom1:SemanticRangeStart.Product>
<custom1:SemanticRangeStart.Product>
<t:Products HasChild="True" ID="50" Level="3" Name="OneMore3" ParentID="49" />
</custom1:SemanticRangeStart.Product>
</t:RadDocument>';
SELECT @x;
您可以像这样查询
WITH XMLNAMESPACES('clr-namespace:Telerik.Windows.Documents.Model;assembly=Telerik.Windows.Documents' AS t
,'clr-namespace:TAS2;assembly=RadRichTextBoxExtensions' AS custom1
,DEFAULT 'http://schemas.microsoft.com/winfx/2006/xaml/presentation')
,Numbered AS
(
SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS RowInx
,CASE WHEN The.Node.value('fn:local-name(.)','varchar(max)') = 'RoomGroupRangeStart' THEN 'Room' ELSE 'Product' END AS NodeType
,CAST('<node>' + CAST(The.Node.query('.') AS VARCHAR(MAX)) + '</node>' AS XML) AS TheNode
FROM @x.nodes('/t:RadDocument/*') AS The(Node)
)
,DistinctRooms AS
(
SELECT Numbered.*
,TheNode.value('(*//@RoomID)[1]','int') AS RoomID
,TheNode.value('(*//@RoomName)[1]','varchar(max)') AS RoomName
FROM Numbered
WHERE NodeType='Room'
)
SELECT
dr.*
,RelatedProducts.TheNode.value('(*//@HasChild)[1]','bit') AS HasChild
,RelatedProducts.TheNode.value('(*//@ID)[1]','int') AS ProductID
,RelatedProducts.TheNode.value('(*//@Level)[1]','int') AS Level
,RelatedProducts.TheNode.value('(*//@Name)[1]','varchar(max)') AS ProductName
,RelatedProducts.TheNode.value('(*//@ParentID)[1]','int') AS ParentID
FROM DistinctRooms AS dr
CROSS APPLY
(
SELECT products.*
FROM Numbered AS products
WHERE products.NodeType='Product'
AND products.RowInx BETWEEN dr.RowInx AND (SELECT ISNULL(MIN(x.RowInx),1000000) FROM DistinctRooms AS x WHERE x.RowInx>dr.RowInx )
) AS RelatedProducts;
结果
1 26 Bathroom 1 48 1 Plumbing 1
1 26 Bathroom 1 49 2 Central Heating 48
1 26 Bathroom 1 50 3 Gas 49
5 27 Test 1 48 1 Test1 1
5 27 Test 1 49 2 Test2 48
5 27 Test 1 50 3 Test3 49
9 28 OneMore 1 48 1 OneMore1 1
9 28 OneMore 1 49 2 OneMore2 48
9 28 OneMore 1 50 3 OneMore3 49