Reputation: 71
I want to solve a problem - given an arbitrary sequence of xml paths, I want to generate the xml tree structure:
e.g. given this sequence:
"/person/name" "/person/address" "/person/age" "/person/parent/name"
generate:
<person>
<name></name>
<address></address>
<parent>
<name></name>
</parent>
</person>
Does anyone know of a good example of how to do this in xquery and/or XSLT?
Thanks
Upvotes: 1
Views: 139
Reputation: 433
This is a recursion problem. You want to process all the XPaths at once, but consume them step by step. At each step, identify the distinct elements that needs to be created, create them, and then within each, recursively call the same function on the tails of all the paths that go through that new element.
declare function local:generate($paths) {
if(fn:empty($paths)) then () else
let $heads := $paths ! fn:subsequence(fn:tokenize(.,'/'),1,1)
let $tails := $paths ! fn:string-join(fn:subsequence(fn:tokenize(.,'/'),2),'/')
for $element in fn:distinct-values($heads)
return
if($element='') then local:generate($tails)
else element { xs:QName($element) } {
let $nextPaths := for $tail at $n in $tails where fn:starts-with($paths[$n],$element||'/') return $tail
return local:generate($nextPaths)
}
};
local:generate(("/person/name", "/person/address", "/person/age", "/person/parent/name"))
Upvotes: 4