我的xml是:
<record>
<field name="f1"/>
<id name="f2"/>
<id name="f3"/>
<field name="f4"/>
<info/>
</record>
我想在xquery中循环遍历它:
for $i in $records/record/field | $records/record/id
return
if ( .... $i is id .... ) then .... do something .... else ... do something else ...
这可能吗?如何区分$i
是id和何时是字段?
答案 0 :(得分:4)
另一个简洁的XQuery解决方案是使用typeswitch:
for $i in $records/record/field | $records/record/id
return
typeswitch($i)
case element(id) return ...
case element(field) return ...
default return ...
答案 1 :(得分:2)
我将使用self :: id,例如
,而不是那些使用name()或local-name()的尝试if ($i[self::id]) then ... else ...
答案 2 :(得分:0)
您可以使用函数库或创建自己的用户定义函数。像这样:
for $i in $records/record/field | $records/record/id
return
if (name($i)="id") then .... do something .... else ... do something else ...
答案 3 :(得分:0)
查看local-name
XQuery函数 - 请参阅MSDN docs here。
给定节点或节点集,它应该为您提供节点的名称 - 标签的名称。我猜这就是你要找的,对吧?
E.g。如果你这样做:
DECLARE @input XML = '<record>
<field name="f1"/>
<id name="f2"/>
<id name="f3"/>
<field name="f4"/>
<info/>
</record>'
SELECT
inp.nod.query('local-name(.)')
FROM
@input.nodes('//*') AS inp(nod)
你得到这样的输出:
record
field
id
id
field
info
答案 4 :(得分:0)
如何更简单,更像XQuery
for $i in $records/record/field return do something with field,
for $i in $records/record/id return do something with id
在这种情况下,第一个for返回的值将与第二个for的值合并。
答案 5 :(得分:0)
使用typeswitch:
let $record :=
<record>
<field name="f1"/>
<id name="f2"/>
<id name="f3"/>
<field name="f4"/>
<info/>
</record>
for $e in $record/*
return
typeswitch ($e)
case element(id) return concat("id",$e/@name)
case element (field) return concat("field",$e/@name)
default return "other"