(: use a modified identity function to restructure the original XML :) declare function local:copy($element as element()) as element() { element {node-name($element)} {$element/@*, for $child in $element/node() return if (name($child) ="syllabus") (: syllabus is a summary of the question bank and hence redundant :) then () else if (name($child) = "title") then if (name($child/..) = "subelement") (: get the title prefix and promote the id part to an attribute of the enclosing element - fortuitously the previous element. Trim the title e.g. T1B - Authorized frequencies; frequency allocations, ITU regions, emission type, restricted sub-bands, spectrum sharing, transmissions near band edges :) then (attribute id {substring-before(substring-after($child,"SUBELEMENT ")," -")}, element title {substring-after ($child," - ")} ) else if (name($child/..) = "group") (: simialrly fo rthe group title e.g. T1B - Authorized frequencies; frequency allocations, ITU regions, emission type, restricted sub-bands, spectrum sharing, transmissions near band edges :) then (attribute id {substring-before($child," -")}, element title {substring-after ($child," - ")} ) else $child else if (name($child) = "number") (: promote question number to the id of the question :) then attribute id {$child} else if ($child instance of element()) (: recurse on any other element :) then local:copy($child) else $child } }; let $doc1 := doc("/db/Wiki/Ham/Element2-2010.xml")/pool return local:copy($doc1)