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

trubliphone trubliphone at googlemail.com
Fri May 6 16:29:16 PDT 2011


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:

<?xml version="1.0" encoding="UTF-8"?>

Now, suppose there is a user-provided XPath expression to find
particular nodes in that file:

$query := "//foo/bar"

I can evaluate that expression as follows:

$doc := doc("myDocument.xml")
$nodes := util:eval(concat("$doc",$query)

This will return a sequence:

(<bar>one</bar>, <bar>two</bar>, <bar>three</bar>, <bar>four</bar>,

But I need to recreate the original hierarchical structure of those
nodes.  So what I really want is this:


To help, I can get the "context path" of each node as follows:

$cp :=
    for $ancestor in $node/ancestor-or-self::node()
      let $name := $ancestor/name()
      let $position :=
        return concat("/",$name,"[",$position,"]")

In the above example, this will return the following values for each node:

one:   /root[1]/foo[1]/bar[1]
two:   /root[1]/foo[1]/foo[1]/bar[1]
three: /root[1]/foo[1]/foo[2]/bar[1]
four:  /root[1]/foo[2]/bar[1]
five:   /root[1]/foo[2]/foo[1]/foo[1]/bar[1]

So I have the following sequence to work with:

  <node cp="/root[1]/foo[1]/bar[1]"><bar>one</bar></node>,
  <node cp="/root[1]/foo[1]/foo[1]/bar[1]"><bar>two</bar></node>,
  <node cp="/root[1]/foo[1]/foo[2]/bar[1]"><bar>three</bar></node>,
  <node cp="/root[1]/foo[2]/bar[1]"><bar>four</bar></node>,
  <node cp="/root[1]/foo[2]/foo[1]/foo[1]/bar[1]"><bar>five</bar></node>

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

Many thanks for your help.

More information about the talk mailing list