如何在xpath中获取元素类型?

时间:2010-03-05 06:11:58

标签: xpath xquery

我的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和何时是字段?

6 个答案:

答案 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 ...

http://www.xqueryfunctions.com/xq/fn_name.html

答案 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"