Looking A Nodes From Within Nodes

J

Johnny Ooi

I've written a template that does some work on a subtree, but I want to
replace the subtree that I originally worked on. How would I do this?

Confused, Okay, here's an example:

<node>
<node>
<node>
</node>
<node>
</node>
</node>
<node> **
<node>
</node>
<node>
</node>
</node> **
</node>

This is a binary tree full of "node" tags. Let's let I was working on
the subtree starting at the node tag I've indicated by the **s. Let's
say I've done my work on the subtree and I want to replace the subtree
in this master tree with the one I've just changed. I also want to
change the top level node tag (for example, updating the attribute tag).
I can't do something like

<xsl:element>
<xsl:attribute counter="/node/@counter+1"/>
<xsl:copy-of select="/node/*[position()=1]"/>
<xsl:copy-of select="$outputofsubtreework"/>
</xsl:element>

Because, while it will work in this case, I don't know in advance how
many levels the tree will have.

Can anyone help me out here? :)

Johnny
 
J

Johnny Ooi

Ack! Sorry, I phrased the problem incorrectly. When I said "top level
node tag", I meant to indicate the parent of the root of the subtree.
So, in this example, it's the root of the tree, but in another scenario,
it might not be.

And apologies for the example, by indentations didn't show up correctly.

Johnny
 
J

Joris Gillis

I want to replace the subtree
in this master tree with the one I've just changed. I also want to
change the top level node tag (for example, updating the attribute tag).
I can't do something like

<xsl:element>
<xsl:attribute counter="/node/@counter+1"/>
<xsl:copy-of select="/node/*[position()=1]"/>
<xsl:copy-of select="$outputofsubtreework"/>
</xsl:element>

Because, while it will work in this case, I don't know in advance how
many levels the tree will have.

Hi,

Maybe you can use something like this:

<xsl:element name="node">
<xsl:attribute name="counter"><xsl:value-of select="@counter +1 "/></xsl:attribute>
<xsl:copy-of select="preceding-sibling::*"/>
<xsl:copy-of select="$outputofsubtreework"/>
<xsl:copy-of select="following-sibling::*"/>
</xsl:element>

or, if this doesn't work , give some more details

regards,
 
J

Johnny Ooi

Hi, Joris, thanks for the help, I will try your code out and see if it
works.

Johnny
 
J

Johnny Ooi

Joris, on a side note, can you tell me why doing this:

<xsl:variable>
<xsl:element name="node">
<xsl:attribute name="att1"><xsl:value-of select="'data'"/>
<xsl:attribute name="att2"><xsl:value-of select="'data'"/>
<xsl:element name="node">
<xsl:attribute name="att1"><xsl:value-of select="'data'"/>
<xsl:attribute name="att2"><xsl:value-of select="'data'"/>
</xsl:element>
<xsl:element name="node">
<xsl:attribute name="att1"><xsl:value-of select="'data'"/>
<xsl:attribute name="att2"><xsl:value-of select="'data'"/>
</xsl:element>
</xsl:element>
</xsl:variable>

Gives me a fragment. I was trying to create this tree:

<node att1='data' att2='data'>
<node att1='data' att2='data'/>
<node att1='data' att2='data'/>
</node>

But because it's a fragment, I cannot do anything like
$var/*[position()=1] or $var/* and I need to do that. How should I
restructure my code to give me a nodeset?

Regards

Johnny
 
J

Joris Gillis

Hi,
Joris, on a side note, can you tell me why doing this:
<xsl:variable>
<xsl:element name="node">
<xsl:attribute name="att1">data</xsl:attribute>
<xsl:attribute name="att2">data</xsl:attribute>
<xsl:element name="node">
<xsl:attribute name="att1">data</xsl:attribute>
<xsl:attribute name="att2">data</xsl:attribute>
</xsl:element>
<xsl:element name="node">
<xsl:attribute name="att1">data</xsl:attribute>
<xsl:attribute name="att2">data</xsl:attribute>
</xsl:element>
Gives me a fragment. I was trying to create a tree.

Well, actually it creates a result tree.
It's only impossible (in XSLT 1.0) to consult a fragment of the result tree or apply an Xpath expression on it.
How should I restructure my code to give me a nodeset?
I'm afraid you can't. In XSLT, you can't create nodesets.
You can, however, convert a result tree to a nodeset with an extension function such as 'exsl:node-set()'

regards,
 
J

Johnny Ooi

Forget that last message, I've sorted it out, but the original problem
is still bothering me.
 
J

Joris Gillis

Forget that last message, I've sorted it out, but the original problem
is still bothering me.

What's still bothering you? Give some more details and I'll try to help.

regards,
 
J

Johnny Ooi

How should I restructure my code to give me a nodeset?
I'm afraid you can't. In XSLT, you can't create nodesets.
You can, however, convert a result tree to a nodeset with an extension
function such as 'exsl:node-set()'
<<

However, the problem with that is that extension functions are processor
specific, and not all processors will support them. Am I correct? I am
trying to avoid placing restrictions on my code because of problems like
this, but if I have to, I don't have a choice. Out of curiosity, which
processor does that exsl: prefix come from?


Regards

Johnny
 
J

Joris Gillis

Hi,
The problem with that is that extension functions are processor
specific, and not all processors will support them. Am I correct?
You're absolutely right. That's why I'd never use it myself. My philosophy is: when a general feature is missing in a W3C recommendation, just wait until the next version is developed; don't use 'extension' functions of any sort or weird hacks: wait until there's a short, standardized way to do it. Off course, this philosophy is very hard to maintain in a professional environment. But, since I'm only a student, I can perfectly afford to think such.
trying to avoid placing restrictions on my code because of problems like
this, but if I have to, I don't have a choice.
There's another option: use 2 stylesheet that are being applied one after each-other.
Or you could redesign the the algorithm of your XSLT.
Out of curiosity, which processor does that exsl: prefix come from?
I'm not sure. Check http://www.exslt.org/ for that.

regards,
 
J

Johnny Ooi

Joris, you're being a real help here, I really appreciate your
assistance. I'm still fairly new to XSL, so I've having lots of
problems.

The original problem was this: I have a binary tree and I'm working on a
subtree of this master tree. I want to replace an attribute value on the
root of the tree, but I can't say in advance how many levels there will
be between the root of the subtree and the root of the master tree. In
fact, the subtree result will not be in the same order as the original
subtree I started working with (e.g. the attributes will be different).

What I would like to know is how can I replace the subtree on the master
tree and update the root node's attribute, given that I can't say in
advance how many levels there will be between the subtree and the root.
So in one scenario, soing $current/../../.. (root + 3 levels) will get
you to the root, but in another, $current/.. (root + 1 level) will do
the same.

I know you can't change the contents of variables, so if the master tree
was in a variable called "tree", I'd have to put the result of the
subtree replace in a variable called "tree2" or something else along
those lines.

I hope this helps you understand the problem I'm having.

Johnny
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,575
Members
45,053
Latest member
billing-software

Latest Threads

Top