获取XML中每个标签的名称

Get the name of each tag 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|

我该怎么办?由于我在该存储过程的其他部分使用了OPENXML,所以最好使用OPENXML函数来获取它。

我已经试过了

SELECT localname
FROM OPENXML(@idoc, '/A') 
WHERE localname!='A'

获取标签名称。但是,我无法使用标签 A 的属性加入它们。

首先要说的是:FROM OPENXML 已经过时,不应再使用(存在极少数例外)。最好使用 XML 数据类型的 native XML methods

其次:您的 XML 严格来说格式不正确。应该有一个根元素,而第一层有几个 <A> 元素。很高兴 SQL-服务器允许 XML 片段。所以这会起作用...

像这样尝试

DECLARE @xml XML=
N'<A name="x1">
    <B/>
    <C/>
    <D/>
</A>
<A name="x2">
    <E/>
    <F/>
</A>';

SELECT AllA.value('@name','varchar(100)') AS A_name
      ,Children.value('local-name(.)','nvarchar(max)') AS tag_name
FROM @xml.nodes('/A') A(AllA)
OUTER APPLY AllA.nodes('*') B(Children);

简而言之:

  • 我们使用.nodes()来检索重复的<A>个元素
  • 我们使用.value()<A>
  • 读取name属性
  • 我们使用 APPLY 和另一个 .nodes() 调用来检索 <A>.
  • 以下的所有元素
  • 现在我们可以使用 .value()local-name() 来读取元素的名称。