I am relatively new to xQuery and don't use it very often, and I have what's likely a relatively simple question that I just don't know the answer to. How do you apply a function recursively when you have to compare against a parent/child combination rather than a single element in a for loop?
I have a set of data where I have several parent/child element sets with @xml:id attributes
<root>
<something>
</something>
<somethingElse>
<parent @xml:id="p.1">
<child @xml:id="c.1">
<grandchild/>
</child>
<child @xml:id="c.2">
<grandchild/>
</child>
</parent>
<parent @xml:id ="p.2">
<child @xml:id="c.1">
<grandchild/>
</child>
</parent>
</somethingElse>
</root>
I need to be able to add an attribute to a specific child of a specific parent, like so
<root>
<something>
</something>
<somethingElse>
<parent @xml:id="p.1">
<child @xml:id="c.1">
<grandchild/>
</child>
<child @xml:id="c.2" active="yes">
<grandchild/>
</child>
</parent>
<parent @xml:id ="p.2">
<child @xml:id="c.1">
<grandchild/>
</child>
</parent>
</somethingElse>
</root>
In looking at what's already been done the functx library function add-attributes will do this
declare function functx:add-attributes
( $elements as element()* ,
$attrNames as xs:QName* ,
$attrValues as xs:anyAtomicType* ) as element()? {
for $element in $elements
return element { node-name($element)}
{ for $attrName at $seq in $attrNames
return if ($element/@*[node-name(.) = $attrName])
then ()
else attribute {$attrName}
{$attrValues[$seq]},
$element/@*,
$element/node() }
} ;
but when I apply this to my data(as $body) via the let
statement let $bodynew := functx:add-attributes($body//parent[@xml:id='p.1']/child[@xml:id='c.2'], xs:QName('active'), 'yes')
I only get the following:
<child @xml:id="c.2" active="yes">
<grandchild/>
</child>
I understand why I'm only getting the single child
element back, but I'm not sure how to return all of the XML, with the change made by the function, when I'm checking against a parent/child combination as I am here since I can't just apply the function to a single element in a for loop. Any help that could be given would be great.