[xquery-talk] creating tree from sequence (from tree)

G. Ken Holman gkholman at CraneSoftwrights.com
Sat May 7 05:16:17 PDT 2011

At 2011-05-06 16:29 -0700, trubliphone wrote:
>I have an algorithmic problem I haven't been able to solve.  I was
>hoping somebody on this list could offer me some advice.
>Suppose I have some arbitrary XML file:

Given the nested in this file, I was immediately drawn to using XSLT 
and not XQuery.  After solving the problem very succinctly in XSLT, 
that guided me in the writing of an XQuery solution.

>Now, suppose there is a user-provided XPath expression to find
>particular nodes in that file:
>$query := "//foo/bar"

My solution is not so parameterized because neither XSLT nor XQuery 
have an eval() that would allow such an XPath expression to be 
dynamically evaluated as either a select expression or a match 
expression.  Plus, I think starting at the bar elements presupposes 
an inefficient pull-style solution rather than a push-style solution.

So you can ignore my answer if you wish, but for a push-style 
solution, please see the code below.

>My question is how to turn that into a tree that recreates the
>original hierarchical structure?

I think it is more efficient to work from the original hierarchical 
structure and create the tree that you need.

I hope you find the solutions below helpful.

. . . . . . . . .  Ken

T:\ftemp>type t.xml
<?xml version="1.0" encoding="UTF-8"?>
T:\ftemp>xquery t.xq
<?xml version="1.0" encoding="UTF-8"?>
T:\ftemp>type t.xq
declare function local:match( $nodes as node()* ) as node()*
   for $node in $nodes return
     typeswitch( $node )
       case element(foo) return if( $node/bar )
                                then <bar>
                                   else local:match( $node/foo )
       default return if( $node/self::text()/parent::bar ) then $node else ()

local:match( doc('t.xml')/root/* )
T:\ftemp>xslt t.xml t.xsl
<?xml version="1.0" 
T:\ftemp>type t.xsl
<?xml version="1.0" encoding="US-ASCII"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

<xsl:template match="root/text() | foo/text()"/>

<xsl:template match="foo[bar]">
     <xsl:apply-templates select="bar/node()"/>
     <xsl:apply-templates select="foo"/>


Contact us for world-wide XML consulting & instructor-led training
Crane Softwrights Ltd.          http://www.CraneSoftwrights.com/q/
G. Ken Holman                 mailto:gkholman at CraneSoftwrights.com
Legal business disclaimers:  http://www.CraneSoftwrights.com/legal

More information about the talk mailing list