xsl-list
[Top] [All Lists]

Re: [xsl] Subtree Transformation

2007-03-15 05:06:18
Garvin Riensche wrote:

I am wondering if it is possible to change a subtree of an XML tree whose structure is not always the same.

well, that is precisely what xslt is all about, and it's good at it ;)




If the input would always look like this I would write a stylesheet that looks like the following:

<xsl:stylesheet match="/">
<a>
  <b>
    <xsl:copy-of="/a/b/c"/>

this is not a good idea, use template matching.



I need to copy everything and add some additional "<c>" tags. I dont't know how to do that becase with xsl:copy-of I can copy the whole tree but it can not be changed and if I iterate trough the tree with xsl:copy every tag is immideately closed. It would be nice if someone could help.

XSLT does not work with tags, it works with nodes (subtle but important difference). An element node is always closed, there is no such thing as an open node. When serialized, this results in a pair opening and closing tags, always.

This must be the single most frequently asked question on this list. What you need is <xsl:copy /> and not <xsl:copy-of /> (shallow copy versus deep copy) and make a modified identity template. Like so:

<xsl:template match="/>
  <xsl:apply-templates select="a" />
</xsl:template>

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

<xsl:template match="c">
<!-- first copy the original 'c' node and all attributes + descendants -->
  <xsl:copy>
     <xsl:apply-templates select="node() | @*" />
  </xsl:copy>

 <!-- second, make additional 'c' nodes -->
 <c id="2" />
 <c id="3" />
</xsl:template>


I advice you to look up a tutorial book (Jeni Tennison's come to mind) or an online tutorial that helps you with understanding template matching, where you declare the rules (you define what outcome you want) and the processor does the math for you based on your input. In this case, the less general match for 'c' has precedence and will be called instead of the general match 'node()' (which does nothing more than shallow copy).

Happy coding!

Cheers,
-- Abel Braaksma




--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--

<Prev in Thread] Current Thread [Next in Thread>