Robert
Robert

Reputation: 71

Given a sequence of XML paths, generate the XML tree structure

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

Answers (1)

BenW
BenW

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

Related Questions