By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
459,290 Members | 1,666 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 459,290 IT Pros & Developers. It's quick & easy.

XSLT: Edit, remove, add nodes specified by position

P: n/a
How can XSLT stylesheets be used to edit, remove and add nodes specified
by their position in the document tree?

The XML document stores development tasks in a hierarchical way, i.e.
tasks can have subtasks, subsubtasks, etc. It has the following form:

<todo>
<note>Task 1</note>
<note>
Task 2
<note>
Task 2.1
</note>
<note>
Task 2.2
</note>
</note>
<note>Task 3</note>
</todo>

The aim is to implement a web interface for task management in
development projects, using parameterised XSLT stylesheets, and some cgi
scripts invoking an XSLT processor to modify the task database.

Is this choice of technologies sensible, or are there better ways to
operate on the XML document?

The stylesheets would be passed the position of the node in the document
tree, i.e. "2.2" would refer to the second subtask of the second task in
the todo list. This node would be removed or edited, or become the
parent of a new subtask (`add').

Can you give me some tips or pointers on how to add, remove and edit
nodes?

I got as far as the following for removing nodes. Of course, this would
need to be negated in some form to remove the corresponding node.

========================XSL======================= =======
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<xsl:copy-of select="todo/note[2]/note[2]"/>
</xsl:template>
</xsl:stylesheet>
========================XSL======================= =======

tia,

Claudio
PS. The XML format originates from the software package devtodo, which
is provides an interactive command-line based interface to the XML
database.

http://swapoff.org/DevTodo

--
http://www.jolowicz.com
Jul 20 '05 #1
Share this Question
Share on Google+
2 Replies


P: n/a
On Tue, 15 Feb 2005, Claudio Jolowicz wrote:
I got as far as the following for removing nodes. Of course, this would
need to be negated in some form to remove the corresponding node.

========================XSL====================== ========
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<xsl:copy-of select="todo/note[2]/note[2]"/>
</xsl:template>
</xsl:stylesheet>
========================XSL====================== ========

I've figured out I have to use the identity transform, but failed to
find a way to parametrise the stylesheet. This one doesn't work because
the match attribute must be a pattern, not an expression (correct?):

========================XSL2====================== ========
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="taskpath"/>

<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>

<xsl:template match="$taskpath"/>
</xsl:stylesheet>
========================XSL2====================== ========
And this one didn't work either, probably because xsl:attribute applies
only to result node, not to the xml:template in which it occurs here.

========================XSL3====================== ========
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="taskid"/>

<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>

<xsl:template>
<xsl:attribute name="match">
<xsl:text>todo</xsl:text>
<xsl:call-template name="split">
<xsl:with-param name="str" select="$taskid"/>
</xsl:call-template>
</xsl:attribute>
</xsl:template>

<xsl:template name="split">
<xsl:param name="str"/>
<xsl:choose>
<xsl:when test="contains($str,'.')">
<xsl:text>/note[</xsl:text>
<xsl:value-of select="substring-before($str,'.')"/>
<xsl:text>]</xsl:text>
<xsl:call-template name="split">
<xsl:with-param name="str" select="substring-after($str,'.')"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:text>/note[</xsl:text>
<xsl:value-of select="$str"/>
<xsl:text>]</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
========================XSL3====================== ========

Any ideas? At the moment I'm resorting to generating the stylesheet
dynamically with perl... Is it really not possible to use parameters
here?

Claudio

--
http://www.jolowicz.com
Jul 20 '05 #2

P: n/a

<xsl:template match="node()|@*">
<xsl:choose>
<xsl:when test="local-name()="$something">
<xsl:call-template name="whatever"/>
</xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
Jul 20 '05 #3

This discussion thread is closed

Replies have been disabled for this discussion.