你好,我有一个新手问题,道歉。
我必须使用愚蠢设计的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>'
由于
答案 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