从sql server 2014获取结构不良的xml数据

时间:2017-10-23 17:19:04

标签: sql-server xml xquery

你好,我有一个新手问题,道歉。

我必须使用愚蠢设计的XML格式 它提供对象属性数据作为标签和a 标签值更改它意味着一个属性。 没有提供属性的地方,例如。哺乳动物,它意味着 价值未知。

以下面的例子为例: 第三级标记可以是20个不同值之一。 第4级标签(哺乳动物)可以是几个值之一 可能不存在。

如何编写XQuery命令以超越 未知/遗失标签?

选择        t.c.value('v [1]','varchar(100)')作为动物 来自@ xml.nodes('/ recs / rec / / a1 / / as t.c

declare @xml xml =
'
<recs>
        <rec>
        <a>
            <a1>
                <mammal>
                    <v>dog</v>
                </mammal>
            </a1>
        </a>
    </rec>
    <rec>
        <b>
            <a1>
                <mammal>
                    <v>cat</v>
                </mammal>
            </a1>
        </b>
    </rec>
    <rec>
        <b>
            <a1>
                <v>pig</v>
            </a1>
        </b>
    </rec>
</recs>'

由于

2 个答案:

答案 0 :(得分:1)

要检索第五级的所有元素,请使用

/*/*/*/*/*

在您显示的输入中,这将检索两个mammal元素和一个pig。 (你说mammal处于第四级;似乎是从零开始计算;我从一个计算。)如果你想要他们的孩子,而是添加一个/*

如果您只想在特定上下文中使用第五级或第六级元素,您当然可以用更严格的内容替换星号:

/recs/rec/b/a1/*

为第五级,

/recs/rec/b/a1/*/*

为第六个。

答案 1 :(得分:1)

不,您无需计算级别并合并*

的正确计数

试试这个,它使用深度搜索//

SELECT any_v.value('text()[1]','nvarchar(max)') AS TheTextWithinV
      ,any_v.value('local-name(..)','nvarchar(max)') AS TheNameOfTheParent
FROM @xml.nodes('//v') AS DeepSearch(any_v);

因为你应该尽可能具体我建议.nodes()

FROM @xml.nodes('/recs/rec//v') AS DeepSearch(any_v);

它将沿着路径向下<rec>然后进行深度搜索直到<v>

由于任何地方都没有其他text(),您甚至可以这样做:

SELECT any_v.value('.','nvarchar(max)') AS FirstTextFound
FROM @xml.nodes('/recs/rec') AS DeepSearch(any_v);

更新另一种方法

试试这个

SELECT r.value('local-name(.)','nvarchar(max)') AS Level2
      ,r.value('local-name((./*)[1])','nvarchar(max)') AS Level3
      ,r.value('if(local-name((./*/*)[1])="v") then "" else local-name((./*/*)[1])','nvarchar(max)') AS Level4
      ,r.value('(.//v/text())[1]','nvarchar(max)') AS Level5
FROM  @xml.nodes('/recs/rec/*') AS A(r);

要得到这个

Level2  Level3  Level4  Level5
a       a1      mammal  dog
b       a1      mammal  cat
b       a1              pig