在 XML 中获取标签和属性的名称
Get the name of tag and attribute in XML
我必须处理具有以下格式的 XML 文件:
<Root>
<A name="x1">
<B exp="h1", ref="r1"/>
<C exp="h2", ref="r2", rat = "ra1"/>
<D exp="h3", ref="r3"/>
</A>
<A name="x2">
<E exp="h4", ref="r4"/>
<F exp="h5", ref="r5"/>
</A>
</Root>
我想写一个存储过程来得到一个 table 比如:
|A_name|tag_name|attrbute|val|
|x1 | B |exp|h1|
|x1 | B |ref|r1|
|x1 | C |exp|h2|
|x1 | C |rat|ra1|
|x1 | C |ref|r2|
|x1 | D |exp|h3|
|x1 | D |ref|r3|
|x2 | E |exp|h4|
|x2 | E |ref|r4|
|x2 | F |exp|h5|
|x2 | F |ref|r5|
我该怎么办?我已经试过了
SELECT localname
FROM OPENXML(@idoc, '/A')
WHERE localname!='A'
获取标签名称。但是,我无法使用标签 A 的属性加入它们。
如果您的初始数据有误(并且没有使用逗号分隔标签)您可以试试这个:
DECLARE @XML XML = N'<Root>
<A name="x1">
<B exp="h1" ref="r1"/>
<C exp="h2" ref="r2" rat = "ra1"/>
<D exp="h3" ref="r3"/>
</A>
<A name="x2">
<E exp="h4" ref="r4"/>
<F exp="h5" ref="r5"/>
</A>
</Root>'
SELECT [A_name]
,[B_name]
,attribute
,value
FROM
(
SELECT T1.c.value('(./@name)[1]', 'varchar(12)') as [A_name]
,T2.c.value('local-name(.)', 'varchar(12)') as [B_name]
,T2.c.value('(@exp)[1]', 'varchar(30)') AS [exp]
,T2.c.value('(@ref)[1]', 'varchar(30)') AS [ref]
,T2.c.value('(@rat)[1]', 'varchar(30)') AS [rat]
FROM @XML.nodes('Root/A') T1(c)
CROSS APPLY T1.c.nodes('./*') T2(c)
) DS
UNPIVOT
(
[value] for [attribute] IN ([exp], [ref], [rat])
) UNPVT;
类似于 gotqn 的答案...您可以通过 @*
通配符查询获取元素的所有属性,从而避免枢轴(这需要提前了解所有属性名称) , 例如:
select
a.a.value('(@name)[1]', 'nvarchar(50)') as 'a_name',
b.b.value('local-name(.)', 'nvarchar(50)') as 'tag_name',
c.c.value('local-name(.)', 'nvarchar(50)') as 'attribute',
c.c.value('data(.)', 'nvarchar(50)') as 'val'
from @example.nodes('//A') a(a)
cross apply a.a.nodes('*') b(b)
cross apply b.b.nodes('@*') c(c);
| a_name | tag_name | attribute | val |
|--------|----------|-----------|-----|
| x1 | B | exp | h1 |
| x1 | B | ref | r1 |
| x1 | C | exp | h2 |
| x1 | C | ref | r2 |
| x1 | C | rat | ra1 |
| x1 | D | exp | h3 |
| x1 | D | ref | r3 |
| x2 | E | exp | h4 |
| x2 | E | ref | r4 |
| x2 | F | exp | h5 |
| x2 | F | ref | r5 |
我必须处理具有以下格式的 XML 文件:
<Root>
<A name="x1">
<B exp="h1", ref="r1"/>
<C exp="h2", ref="r2", rat = "ra1"/>
<D exp="h3", ref="r3"/>
</A>
<A name="x2">
<E exp="h4", ref="r4"/>
<F exp="h5", ref="r5"/>
</A>
</Root>
我想写一个存储过程来得到一个 table 比如:
|A_name|tag_name|attrbute|val|
|x1 | B |exp|h1|
|x1 | B |ref|r1|
|x1 | C |exp|h2|
|x1 | C |rat|ra1|
|x1 | C |ref|r2|
|x1 | D |exp|h3|
|x1 | D |ref|r3|
|x2 | E |exp|h4|
|x2 | E |ref|r4|
|x2 | F |exp|h5|
|x2 | F |ref|r5|
我该怎么办?我已经试过了
SELECT localname
FROM OPENXML(@idoc, '/A')
WHERE localname!='A'
获取标签名称。但是,我无法使用标签 A 的属性加入它们。
如果您的初始数据有误(并且没有使用逗号分隔标签)您可以试试这个:
DECLARE @XML XML = N'<Root>
<A name="x1">
<B exp="h1" ref="r1"/>
<C exp="h2" ref="r2" rat = "ra1"/>
<D exp="h3" ref="r3"/>
</A>
<A name="x2">
<E exp="h4" ref="r4"/>
<F exp="h5" ref="r5"/>
</A>
</Root>'
SELECT [A_name]
,[B_name]
,attribute
,value
FROM
(
SELECT T1.c.value('(./@name)[1]', 'varchar(12)') as [A_name]
,T2.c.value('local-name(.)', 'varchar(12)') as [B_name]
,T2.c.value('(@exp)[1]', 'varchar(30)') AS [exp]
,T2.c.value('(@ref)[1]', 'varchar(30)') AS [ref]
,T2.c.value('(@rat)[1]', 'varchar(30)') AS [rat]
FROM @XML.nodes('Root/A') T1(c)
CROSS APPLY T1.c.nodes('./*') T2(c)
) DS
UNPIVOT
(
[value] for [attribute] IN ([exp], [ref], [rat])
) UNPVT;
类似于 gotqn 的答案...您可以通过 @*
通配符查询获取元素的所有属性,从而避免枢轴(这需要提前了解所有属性名称) , 例如:
select
a.a.value('(@name)[1]', 'nvarchar(50)') as 'a_name',
b.b.value('local-name(.)', 'nvarchar(50)') as 'tag_name',
c.c.value('local-name(.)', 'nvarchar(50)') as 'attribute',
c.c.value('data(.)', 'nvarchar(50)') as 'val'
from @example.nodes('//A') a(a)
cross apply a.a.nodes('*') b(b)
cross apply b.b.nodes('@*') c(c);
| a_name | tag_name | attribute | val |
|--------|----------|-----------|-----|
| x1 | B | exp | h1 |
| x1 | B | ref | r1 |
| x1 | C | exp | h2 |
| x1 | C | ref | r2 |
| x1 | C | rat | ra1 |
| x1 | D | exp | h3 |
| x1 | D | ref | r3 |
| x2 | E | exp | h4 |
| x2 | E | ref | r4 |
| x2 | F | exp | h5 |
| x2 | F | ref | r5 |