Subject: Re: Copying elements and their attributes From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx> Date: Tue, 03 Oct 2000 18:55:19 +0100 |
Chris, The crux of your problem lies in understanding what xsl:value-of gives when you apply it to an element. In your input you have: <code type="xml"> <foo type="fooed"> <bar>test text</bar> </foo> </code> When you do: <xsl:value-of select="." /> it gives you the 'string value' of the current node. For an element, the string value is the concatenation of all the text descendents of the element. This can be really useful when you have mixed content - for example in: <p>Text with <em>emphasis</em> in it.</p> the 'string value' of the 'p' element is "Text with emphasis in it." - very handy if you don't care about the emphasis existing or not. The problem is that in your case the elements 'code', 'foo' and 'bar' all have more or less the same string value (aside from the odd bit of whitespace here and there). In your template: <xsl:template match="@*|node()" mode="code"> <fo:block text-align="start" line-height="1.5" font-family="Courier" start-indent="20pt" end-indent="20pt" > <fo:inline-sequence color="silver"><<xsl:value-of select="name()"/>></fo:inline-sequence> <fo:inline-sequence color="#B00"><xsl:value-of select="."/></fo:inline-sequence> <xsl:apply-templates mode="code"/> <fo:inline-sequence color="silver"></<xsl:value-of select="name()"/>></fo:inline-sequence> </fo:block> </xsl:template> when the 'code' element is processed by the template, the inline-sequence: <fo:inline-sequence color="#B00"> <xsl:value-of select="."/> </fo:inline-sequence> gives the string value of the 'code' element (i.e. "test text"). You then apply templates to the 'code' element's children (the 'foo' element), and so the template is used again, this time on the 'foo' element, giving its string value (i.e. "test text"), again applying templates to its children (the 'bar' element), and therefore again emitting "test text". This is why you end up with three copies of the text! The solution to this problem is to have a separate template that emits the fo:inline-sequence for any text that's found, and let the generic xsl:apply-templates deal with applying this template when there's text to apply it to. Take out the section in your template that includes the value of the current node, and add an extra template that matches text() nodes: <xsl:template match="text()" mode="code"> <fo:inline-sequence color="#B00"> <xsl:value-of select="."/> </fo:inline-sequence> </xsl:template> There are a couple of other problems with the template. Firstly, it matches on any kind of node() (and on attributes - which are themselves a type of node) whereas you actually want it to only apply to elements. Secondly, it doesn't do anything about the attributes that you want included - you need to apply templates specifically to emit them. Here are three templates that may do roughly what you want (the colours might need changing a bit, and I don't know much about formatting objects, so I might have done something illegal with them): <xsl:template match="*" mode="code"> <fo:block text-align="start" line-height="1.5" font-family="Courier" start-indent="20pt" end-indent="20pt" > <fo:inline-sequence color="silver"> <xsl:text><</xsl:text> <xsl:value-of select="name()"/> <xsl:apply-templates select="@*" mode="code" /> <xsl:text>></xsl:text> </fo:inline-sequence> <xsl:apply-templates mode="code" /> <fo:inline-sequence color="silver"> <xsl:text /></<xsl:value-of select="name()"/>><xsl:text /> </fo:inline-sequence> </fo:block> </xsl:template> <xsl:template match="@*" mode="code"> <xsl:text> </xsl:text> <fo:inline-sequence color="blue"> <xsl:value-of select="name()" />="<xsl:text /> <fo:inline-sequence color="#B00"> <xsl:value-of select="." /> </fo:inline-sequence> <xsl:text>"</xsl:text> </fo:inline-sequence> </xsl:template> <xsl:template match="text()" mode="code"> <fo:inline-sequence color="#B00"> <xsl:value-of select="."/> </fo:inline-sequence> </xsl:template> I hope that this helps, Jeni Jeni Tennison http://www.jenitennison.com/ XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
msoft problems sorting, Jason Thomas | Thread | MSXML3 XSL namespace conflict?, Friedlander, Hal |
RE: Problems with XSL, XML code, Evan Lenz | Date | MSXML3 XSL namespace conflict?, Friedlander, Hal |
Month |