使用属性解析 XML
Parse XML with Attributes
给定一个具有以下结构的 XML:
<someStructure>
<Tag1 Qualifier = "QQ" Name = "Name">
<Tag2 Code = "CD" Name = "SomeName">
<Tag3 Qualifier = "QW" Number = "22"/>
</Tag2>
</Tag1>
<Tag1 Qualifier = "NN" Name = ""/>
<Tag1 Qualifier = "QE" Name = "Name2">
<Tag2 Code = "CD" Name = "SomeName2">
<Tag3 Qualifier = "QW" Number = "22"/>
</Tag2>
</Tag1>
</someStructure>
是否可以通过 1 个查询来解析结果?
我可以用 XML.nodes 解析每一行并将其作为 value() 但我无法获取子节点的结果。
我想做这样的事情
SELECT b.value('@Qualifier', 'nvarchar(max)'),b.value('@Name', 'nvarchar(max)'),
b.value('/Tag2/@Code', 'nvarchar(max)'),b.value('/Tag2/@Name', 'nvarchar(max)'),
b.value('/Tag2/Tag3/@Qualifier', 'nvarchar(max)'),b.value('/Tag2/Tag3/@Number', 'nvarchar(max)')
FROM @xml.nodes('/someStructure/Tag1') as a(b)
但是我收到这个错误:
Msg 2389, Level 16, State 1, Procedure spParse_XML, Line 96 [Batch
Start Line 0] XQuery [value()]: 'value()' requires a singleton (or
empty sequence), found operand of type 'xdt:untypedAtomic *'
我已经设法通过解析不同查询中的每一行来获得预期值,但我确信这不是最好的方法..
SELECT b.value('@Qualifier', 'nvarchar(max)'),b.value('@Name', 'nvarchar(max)')
FROM @xml.nodes('/someStructure/Tag1') as a(b)
SELECT b.value('@Code', 'nvarchar(max)'),b.value('@Name', 'nvarchar(max)')
FROM @xml.nodes('/someStructure/Tag1/Tag2') as a(b)
SELECT b.value('@Qualifier', 'nvarchar(max)'),b.value('@Name', 'nvarchar(max)')
FROM @xml.nodes('/someStructure/Tag1/Tag2/Tag3') as a(b)
正如错误告诉您的那样,您还没有定义单例,它定义了值来自哪个编号节点。您很可能只想要第一个节点。我还更改了你的数据类型,因为我 怀疑 你的值最多可以有 10 亿个字符(尽管我对大多数使用 nvarchar(2)
,这可能不够长在所有地方)。
这给出了如下内容:
DECLARE @XML xml = '<someStructure>
<Tag1 Qualifier = "QQ" Name = "Name">
<Tag2 Code = "CD" Name = "SomeName">
<Tag3 Qualifier = "QW" Number = "22"/>
</Tag2>
</Tag1>
<Tag1 Qualifier = "NN" Name = ""/>
<Tag1 Qualifier = "QE" Name = "Name2">
<Tag2 Code = "CD" Name = "SomeName2">
<Tag3 Qualifier = "QW" Number = "22"/>
</Tag2>
</Tag1>
</someStructure>';
SELECT sS.T1.value('(@Qualifier)[1]','nvarchar(2)') AS Tag1Qualifier, --Does this "need" to be up to 1 billion characters long?
sS.T1.value('(@Name)[1]','nvarchar(20)') AS Tag1Name, --Does this "need" to be up to 1 billion characters long?
sS.T1.value('(Tag2/@Code)[1]','nvarchar(2)') AS Tag2Code, --Does this "need" to be up to 1 billion characters long?
sS.T1.value('(Tag2/@Name)[1]','nvarchar(20)') AS Tag2Name, --Does this "need" to be up to 1 billion characters long?
sS.T1.value('(Tag2/Tag3/@Qualifier)[1]','nvarchar(2)') AS Tag3Qualifier, --Does this "need" to be up to 1 billion characters long?
sS.T1.value('(Tag2/Tag3/@Number)[1]','int') AS Tag3Number --Does this "need" to be up to 1 billion characters long?
FROM (VALUES(@XML))V(X)
CROSS APPLY V.X.nodes('/someStructure/Tag1') sS(T1);
给定一个具有以下结构的 XML:
<someStructure>
<Tag1 Qualifier = "QQ" Name = "Name">
<Tag2 Code = "CD" Name = "SomeName">
<Tag3 Qualifier = "QW" Number = "22"/>
</Tag2>
</Tag1>
<Tag1 Qualifier = "NN" Name = ""/>
<Tag1 Qualifier = "QE" Name = "Name2">
<Tag2 Code = "CD" Name = "SomeName2">
<Tag3 Qualifier = "QW" Number = "22"/>
</Tag2>
</Tag1>
</someStructure>
是否可以通过 1 个查询来解析结果?
我可以用 XML.nodes 解析每一行并将其作为 value() 但我无法获取子节点的结果。
我想做这样的事情
SELECT b.value('@Qualifier', 'nvarchar(max)'),b.value('@Name', 'nvarchar(max)'),
b.value('/Tag2/@Code', 'nvarchar(max)'),b.value('/Tag2/@Name', 'nvarchar(max)'),
b.value('/Tag2/Tag3/@Qualifier', 'nvarchar(max)'),b.value('/Tag2/Tag3/@Number', 'nvarchar(max)')
FROM @xml.nodes('/someStructure/Tag1') as a(b)
但是我收到这个错误:
Msg 2389, Level 16, State 1, Procedure spParse_XML, Line 96 [Batch Start Line 0] XQuery [value()]: 'value()' requires a singleton (or empty sequence), found operand of type 'xdt:untypedAtomic *'
我已经设法通过解析不同查询中的每一行来获得预期值,但我确信这不是最好的方法..
SELECT b.value('@Qualifier', 'nvarchar(max)'),b.value('@Name', 'nvarchar(max)')
FROM @xml.nodes('/someStructure/Tag1') as a(b)
SELECT b.value('@Code', 'nvarchar(max)'),b.value('@Name', 'nvarchar(max)')
FROM @xml.nodes('/someStructure/Tag1/Tag2') as a(b)
SELECT b.value('@Qualifier', 'nvarchar(max)'),b.value('@Name', 'nvarchar(max)')
FROM @xml.nodes('/someStructure/Tag1/Tag2/Tag3') as a(b)
正如错误告诉您的那样,您还没有定义单例,它定义了值来自哪个编号节点。您很可能只想要第一个节点。我还更改了你的数据类型,因为我 怀疑 你的值最多可以有 10 亿个字符(尽管我对大多数使用 nvarchar(2)
,这可能不够长在所有地方)。
这给出了如下内容:
DECLARE @XML xml = '<someStructure>
<Tag1 Qualifier = "QQ" Name = "Name">
<Tag2 Code = "CD" Name = "SomeName">
<Tag3 Qualifier = "QW" Number = "22"/>
</Tag2>
</Tag1>
<Tag1 Qualifier = "NN" Name = ""/>
<Tag1 Qualifier = "QE" Name = "Name2">
<Tag2 Code = "CD" Name = "SomeName2">
<Tag3 Qualifier = "QW" Number = "22"/>
</Tag2>
</Tag1>
</someStructure>';
SELECT sS.T1.value('(@Qualifier)[1]','nvarchar(2)') AS Tag1Qualifier, --Does this "need" to be up to 1 billion characters long?
sS.T1.value('(@Name)[1]','nvarchar(20)') AS Tag1Name, --Does this "need" to be up to 1 billion characters long?
sS.T1.value('(Tag2/@Code)[1]','nvarchar(2)') AS Tag2Code, --Does this "need" to be up to 1 billion characters long?
sS.T1.value('(Tag2/@Name)[1]','nvarchar(20)') AS Tag2Name, --Does this "need" to be up to 1 billion characters long?
sS.T1.value('(Tag2/Tag3/@Qualifier)[1]','nvarchar(2)') AS Tag3Qualifier, --Does this "need" to be up to 1 billion characters long?
sS.T1.value('(Tag2/Tag3/@Number)[1]','int') AS Tag3Number --Does this "need" to be up to 1 billion characters long?
FROM (VALUES(@XML))V(X)
CROSS APPLY V.X.nodes('/someStructure/Tag1') sS(T1);