tags:

views:

29

answers:

1

Hi all!

I have this Xml:

<Item key = "id">
   <SubItem id = "1" a = "2"/>
   <SubItem id = "1" b = "3"/>
   <SubItem x = "1"/>
   <SubItem y = "1"/>
   <SubItem z = "1"/>
</Item>

I wish to select the SubItems that have an attribute whose name equals the value of. key

Meaning I want a query that returns these guys:

<SubItem id = "1" a = "2"/>
<SubItem id = "1" b = "3"/>

So I tried:

let $x := ... my xml here...
let $key = $x/@id

return $x/*/@*[name(.) = $key]/..

this works...

but I wanted something more succinct like:

let $x := ... my xml here...
let $key = $x/@id

return $x/*/@$key

problem is, that does not compile because it won't let me use a non literal (or wildcard) after the @.

Is it really impossible? Thanks in advance!!

A: 

You didn't mention what system you're using, but there is a MarkLogic-specific way to do this:

let $data :=
  <Item key = "id">
   <SubItem id = "1" a = "2"/>
   <SubItem id = "1" b = "3"/>
   <SubItem x = "1"/>
   <SubItem y = "1"/>
   <SubItem z = "1"/>
  </Item>
let $path := fn:concat("$data/SubItem[exists(./@", fn:data($data/@key), ")]")
return xdmp:value($path)

As far as I know, standard XQuery doesn't have a simpler way than what you did. Other systems may have similar extensions.

Dave Cassel