Es ist ein wenig über töten sein können, aber ich benutze oft ein TVF zu analysieren und große XML-Dateien Hash. Die Funktion gibt die Daten in einer übergeordneten/untergeordneten Hierarchie mit den Bereichsschlüsseln R1/R2 zurück.
Zum Beispiel:
Declare @XML xml='
<schema fwRel="2">
<taxFormId isPrimeKey="true" fkRef="C1-TXFRM" mapField="TAX_FORM_ID" dataType="string"/>
<formType fkRef="C1-FRMTY" mapField="FORM_TYPE_CD" dataType="string"/>
<bo suppress="true" required="true" fkRef="F1-BUSOB" mapField="BUS_OBJ_CD" dataType="string"/>
<transferReason mdField="C1_TXF_TFRRSN_FLG" dataType="lookup" mapXML="BO_DATA_AREA" lookup="C1_TXF_TFRRSN_FLG"/>
</schema>'
Select * from [dbo].[udf-XML-Hier](@XML) Order by R1
Returns
Sie werden feststellen, es gibt Spalten für Elementname, Attributname, XPath Titel (optional), und Wert. Die R1, R2, Lvl, ID und PT sind alle abgeleitet.
Als TVF, man könnte jede Anwendung WHERE
oder ORDER
gewünschten
Die UDF (mit Original-Quelle), wenn interessiert
CREATE FUNCTION [dbo].[udf-XML-Hier](@XML xml)
Returns Table
As Return
with cte0 as (
Select Lvl = 1
,ID = Cast(1 as int)
,Pt = Cast(NULL as int)
,Element = x.value('local-name(.)','varchar(150)')
,Attribute = cast('' as varchar(150))
,Value = x.value('text()[1]','varchar(max)')
,XPath = cast(concat(x.value('local-name(.)','varchar(max)'),'[' ,cast(Row_Number() Over(Order By (Select 1)) as int),']') as varchar(max))
,Seq = cast(10000001 as varchar(max))
,AttData = x.query('.')
,XMLData = x.query('*')
From @XML.nodes('/*') a(x)
Union All
Select Lvl = p.Lvl + 1
,ID = Cast((Lvl + 1) * 1024 + (Row_Number() Over(Order By (Select 1)) * 2) as int) * 10
,Pt = p.ID
,Element = c.value('local-name(.)','varchar(150)')
,Attribute = cast('' as varchar(150))
,Value = cast(c.value('text()[1]','varchar(max)') as varchar(max))
,XPath = cast(concat(p.XPath,'/',c.value('local-name(.)','varchar(max)'),'[',cast(Row_Number() Over(PARTITION BY c.value('local-name(.)','varchar(max)') Order By (Select 1)) as int),']') as varchar(max))
,Seq = cast(concat(p.Seq,' ',10000000+Cast((Lvl + 1) * 1024 + (Row_Number() Over(Order By (Select 1)) * 2) as int) * 10) as varchar(max))
,AttData = c.query('.')
,XMLData = c.query('*')
From cte0 p
Cross Apply p.XMLData.nodes('*') b(c)
)
, cte1 as (
Select R1 = Row_Number() over (Order By Seq),A.*
From (
Select Lvl,ID,Pt,Element,Attribute,Value,XPath,Seq From cte0
Union All
Select Lvl = p.Lvl+1
,ID = p.ID + Row_Number() over (Order By (Select NULL))
,Pt = p.ID
,Element = p.Element
,Attribute = x.value('local-name(.)','varchar(150)')
,Value = x.value('.','varchar(max)')
,XPath = p.XPath + '/@' + x.value('local-name(.)','varchar(max)')
,Seq = cast(concat(p.Seq,' ',10000000+p.ID + Row_Number() over (Order By (Select NULL))) as varchar(max))
From cte0 p
Cross Apply AttData.nodes('/*/@*') a(x)
) A
)
Select A.R1
,R2 = IsNull((Select max(R1) From cte1 Where Seq Like A.Seq+'%'),A.R1)
,A.Lvl
,A.ID
,A.Pt
,A.Element
,A.Attribute
,A.XPath
,Title = Replicate('|---',Lvl-1)+Element+IIF(Attribute='','','@'+Attribute)
,A.Value
From cte1 A
/*
Source: http://beyondrelational.com/modules/2/blogs/28/posts/10495/xquery-lab-58-select-from-xml.aspx
Declare @XML xml='<person><firstname preferred="Annie" nickname="BeBe">Annabelle</firstname><lastname>Smith</lastname></person>'
Select * from [dbo].[udf-XML-Hier](@XML) Order by R1
*/
Sie den Code erwähnt - können Sie es hinzufügen? – Damian
Irgendwie hat Edge mich geschraubt. Es ist jetzt angebracht –