Very complicated XQuery transformation -


i have complex xquery write (at least standards).

here input xml:

<testrequest>     <request1>        <line>1</line>        <action>addtoname</action>     </request1>     <request2>         <line>2</line>         <action>addtospace</action>     </request2>     <request3>          <line>3<line>          <action>addtospace</action>     </request3> </testrequest> 

in output xml, actions should attached attributes "request1" elements. so, based on action element under request1 element, attribute request1 element should 1 of following:

if action = ignorecase(addtoname), request1 element should <request1 action=insertingname> if action =  ignorecase(addtospace), request1 element should <request1 action=updatingspace> 

not this, also, need add attribute element, based on action values underneath it. so, have traverse each of elements under element , see if of elements equal "addtospace" if yes, need corresponding values of elements , make attribute element. above xml, attribute element should be,

<testrequest linefiller="line 2_* , line 3_*>, 2 , 3 respective line numbers. 

and if there no elements element= addtospace, attribute element should "changed".

so, in summary, transformed xml should this:

<testrequest linefiller="line 2_* , line 3_*>     <request1 action=insertingname>        <line>1</line>        <action>addtoname</action>     </request1>     <request2 action=updatingspace>         <line>2</line>         <action>addtospace</action>     </request2>     <request3 action=updatingspace>          <line>3<line>          <action>addtospace</action>     </request3> </testrequest> 

any accomplish humungous task appreciated.

thanks!!!

you should define functions generate attributes need add elements.

for adding "request" element, should work:

declare function local:getaction($x) {   if (lower-case($x/action) = "addtoname") attribute action {"insertingspace"} else   if (lower-case($x/action) = "addtospace") attribute action {"updatingspace"} else   () }; 

the linefiller attribute can created similarly:

declare function local:getfiller($x) {   attribute linefiller {       if ($x/*[lower-case(action) = "addtospace"])           string-join(           $r in $x/*[lower-case(action) = "addtospace"]             return concat("line ",$r/line,"_*")           , " , ")       else "change"       } }; 

then put together, fun simple loop on original document, adding in attributes needed:

let $doc:=<<your original document>>  return <testrequest> { local:getfiller($doc) } { $r in $doc/* return     element { name($r) } {      local:getaction($r),     $r/*     } } </testrequest> 

edit: enhanced getfiller function return "change" if there no actions


Comments