[xquery-talk] creating tree from sequence (from tree)
trubliphone
trubliphone at googlemail.com
Fri May 6 16:29:16 PDT 2011
Hello,
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"?>
<root>
<foo>
<bar>one</bar>
<foo>
<bar>two</bar>
</foo>
<foo>
<bar>three</bar>
</foo>
</foo>
<foo>
<bar>four</bar>
<foo>
<foo>
<bar>five</bar>
</foo>
</foo>
</foo>
</root>
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>,
<bar>five</bar>)
But I need to recreate the original hierarchical structure of those
nodes. So what I really want is this:
<bar>one
<bar>two</bar>
<bar>three</bar>
</bar>
<bar>four
<bar>five</bar>
</bar>
To help, I can get the "context path" of each node as follows:
$cp :=
string-join(
for $ancestor in $node/ancestor-or-self::node()
let $name := $ancestor/name()
let $position :=
count($ancestor/preceding-sibling::node()[name()=$name])+1
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