5

So I have two nodes of elements that I'm essentially trying to join. I want the top level node to stay the same but the child nodes to be replaced by those cross referenced.

Given:

<stuff>
  <item foo="foo" boo="1"/>
  <item foo="bar" boo="2" />
  <item foo="baz" boo="3"/>
  <item foo="blah boo="4""/>
</stuff>

<list  a="1" b="2">
  <foo>bar</foo>
  <foo>baz</foo>
</list>

I want to loop through "list" and cross reference elements in "stuff" for this result:

<list  a="1" b="2">
  <item foo="bar" boo="2" />
  <item foo="baz" boo="3"/>  
</list>

I want to do this without having to know about what attributes might be on "list". In other words I don't want to have to explicitly call them out like

attribute a { $list/@a }, attribute b { $list/@b }
mbrevoort
  • 5,075
  • 6
  • 38
  • 48

2 Answers2

4

Use:

$list1/item[@foo = $list2/item/@foo]

This selects all <item> elements in $list1 the value of whose foo attribute is equal to the foo attribute of one of the <item> elements in $list2.

In order to copy all attributes of the <list> element, do something like this:

  for $attr in /whateverIsthePathLeadingToList/list/@*
    return 
      attibute {name($attr)} {$attr}
Dimitre Novatchev
  • 240,661
  • 26
  • 293
  • 431
  • for $list in //list return The @* was the big piece I was missing { $list/@* , OTHER STUFF } – mbrevoort Jun 11 '10 at 22:02
  • what is list1 and list2? – bosari May 14 '17 at 17:12
  • `$list1` is a variable that holds the element whose children have to be copied in the result -- in this particular case `$list1` will hold the `` element. `$list2` is a variable that holds the element, whose children-elements are the "filters" -- in this particular case `$list2` will hold the `` element. – Dimitre Novatchev May 14 '17 at 17:25
4

Slightly simplier ... to create a new object from an existing one, but without its children only attributes

assume :

let $old_list :=

This creates a new list copying its attributes

 <list>{$old_list/@*}</list>
DALDEI
  • 3,722
  • 13
  • 9