Sql server 获取XML中标记和属性的名称

Sql server 获取XML中标记和属性的名称,sql-server,xml,tsql,xml-parsing,openxml,Sql Server,Xml,Tsql,Xml Parsing,Openxml,我必须处理以下格式的XML文件: <Root> <A name="x1"> <B exp="h1", ref="r1"/> <C exp="h2", ref="r2", rat = "ra1"/> <D exp="h3", ref="r3"/> </

我必须处理以下格式的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>
我该怎么办?我已经试过了

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;
DECLARE@XML=N'

与gotqn的答案类似。。。您可以通过
@*
通配符查询获得元素的所有属性,从而避免使用枢轴(需要提前知道所有属性名称),例如:

选择
a、 a.value(“(@name)[1]”,“nvarchar(50)”作为“a_name”,
b、 b.值('local-name(.),'nvarchar(50)')作为'tag_name',
c、 c.value('local-name(.),'nvarchar(50)'作为'attribute',
c、 c.值('data(.)','nvarchar(50)')为'val'
来自@example.nodes('//A')A(A)
交叉应用a.a.nodes('*')b(b)
交叉应用b.b.节点('@*')c(c);

您的示例XML不是有效的XML。这真的是你在用逗号工作吗?
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;
| 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  |