I need to display HTML-element in comments (for example)
I use th
It might be possible to replace
<xsl:comment><xsl:apply-templates select="image" /></xsl:comment>
with
<xsl:text disable-output-escaping="yes"><!--</xsl:text>
<xsl:apply-templates select="image" />
<xsl:text disable-output-escaping="yes">--></xsl:text>
Haven't tried though.
<xsl:comment><xsl:apply-templates select="image" /></xsl:comment>
As a result:
<!---->
that is the code in the element xsl:comment ignored
The XSLT 1.0 Spec says:
It is an error if instantiating the content of xsl:comment creates nodes other than text nodes. An XSLT processor may signal the error; if it does not signal the error, it must recover by ignoring the offending nodes together with their content.
How do I display an item in the comments?
It depends what is meant for "display": in a browser:
<-- <xsl:apply-templates select="image" /> -->
may be useful, provided the result of <xsl:apply-templates/>
aboveis just simple text (not markup).
If to "display" means to provide the result as text, then DOE, if allowed by the XSLT processor, may give us the wanted result:
<-- Some text -->
Finally, if it is required that what should be inside the "comment" should be markup and it should be displayed as markup, then this is rather challenging. In this case one has to use:
<xsl:output method="text"/>
and should present every XML lexical item with its desired serialization (i.e. escaped).
This is how the XPath Visualizer constructs its output.
Here is a small transformation that demonstrates the first two approaches:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<-- Hello, World -->
<xsl:text disable-output-escaping="yes"><--</xsl:text>
Hello,world! --<xsl:text disable-output-escaping="yes">></xsl:text>
</xsl:template>
</xsl:stylesheet>
this transformation, when applied on any XML document (not used), produces:
<-- Hello, World -->
<--
Hello,world! -->
Both "comments" may be viewed as comments in a browser, while only the second is presented as comment in free text.
The third approach (most probably what you want) is illustrated below:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<-- <xsl:apply-templates select="image"/> -->
</xsl:template>
<xsl:template match="image">
<img src="<xsl:value-of select="@src"/>"
width="<xsl:value-of select="@width"/>px"
height="<xsl:value-of select="@height"/>px"/>
</xsl:template>
</xsl:stylesheet>
when this transformation is applied on the following XML document:
<image src="http://example.com/yyy.jpg" width="200" height="300"/>
the wanted result is produced:
<--
<img src="http://example.com/yyy.jpg"
width="200px"
height="300px"/>
-->
viewed in a browser as:
<-- <img src="http://example.com/yyy.jpg" width="200px" height="300px"/> -->
From http://www.w3.org/TR/xslt#section-Creating-Comments:
The xsl:comment element is instantiated to create a comment node in the result tree. The content of the xsl:comment element is a template for the string-value of the comment node.
For example, this
<xsl:comment>This file is automatically generated. Do not edit!</xsl:comment>
would create the comment
<!--This file is automatically generated. Do not edit!-->
It is an error if instantiating the content of xsl:comment creates nodes other than text nodes. An XSLT processor may signal the error; if it does not signal the error, it must recover by ignoring the offending nodes together with their content.
It is an error if the result of instantiating the content of the xsl:comment contains the string
--
or ends with-
. An XSLT processor may signal the error; if it does not signal the error, it must recover by inserting a space after any occurrence of-
that is followed by another-
or that ends the comment.
So, in order to do what you want you need to use DOE mechanism.
As example, this stylesheet:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
exclude-result-prefixes="msxsl">
<xsl:output method="html" indent="no" encoding="windows-1251"/>
<xsl:template match="img">
<img src="{.}"/>
</xsl:template>
<xsl:template match="root">
<xsl:variable name="vResult">
<xsl:apply-templates/>
</xsl:variable>
<html>
<xsl:copy-of select="$vResult"/>
<xsl:comment>
<xsl:apply-templates select="msxsl:node-set($vResult)"
mode="encode"/>
</xsl:comment>
</html>
</xsl:template>
<xsl:template match="*" mode="encode">
<xsl:value-of select="concat('<',name())"
disable-output-escaping="yes"/>
<xsl:apply-templates select="@*" mode="encode"/>
<xsl:text>></xsl:text>
<xsl:apply-templates mode="encode"/>
<xsl:value-of select="concat('<',name(),'>')"
disable-output-escaping="yes"/>
</xsl:template>
<xsl:template match="*[not(node())]" mode="encode">
<xsl:value-of select="concat('<',name())"
disable-output-escaping="yes"/>
<xsl:apply-templates select="@*" mode="encode"/>
<xsl:text>/></xsl:text>
</xsl:template>
<xsl:template match="@*" mode="encode">
<xsl:value-of select="concat(' ',name(),'="',.,'"')"/>
</xsl:template>
</xsl:stylesheet>
With this input:
<root>
<img>http://example.org/image1.jpg</img>
<img>http://example.org/image2.jpg</img>
<img>http://example.org/image3.jpg</img>
</root>
Output:
<html>
<img src="http://example.org/image1.jpg">
<img src="http://example.org/image2.jpg">
<img src="http://example.org/image3.jpg">
<!--<img src="http://example.org/image1.jpg"/>
<img src="http://example.org/image2.jpg"/>
<img src="http://example.org/image3.jpg"/>-->
</html>
Note: node-set
extension function for two pass transformation. disable-output-escaping
attribute for xsl:value-of
instruction.
As said before by Dimitri you can't use the xsl:comment instruction.
If your purpose is simply to comment a fragment of tree, the simplest way is to put the comments markers as text (unescaped) like this :
<xsl:text disable-output-escaping="yes"><!--</xsl:text><xsl:apply-templates select="image" /><xsl:text disable-output-escaping="yes">--></xsl:text>
instead of :
<xsl:comment><xsl:apply-templates select="image" /></xsl:comment>
and you will obtain exactly this
<!-- <img src="path" width="100px" height="100px"/> -->
used with msxml and saxon