Simple question. I have an XML file with a few dozens of comment blocks. This is being transformed by a stylesheet to generate an HTML page. However, the comments are ignored with this.
But at the bottom of the generated HTML I would like to have a list of all comments within the XML file. Is that even possible, without the use of anything else than pure XSLT? (No Javascript or whatever!)
As far as I know, this is not possible, but I could be wrong...
The reason the comments aren't processed is that the default template for comments do nothing:
<xsl:template match="processing-instruction()|comment()"/>
See XSLT 1.0 spec "Built-in Template Rules".
If you would like to do something else with comments, you could just create your own matching template and output them as either a new XML comment using xsl:comment or make a HTML list:
<xsl:template match="/">
<ul>
<xsl:apply-templates select="//comment()"/>
</ul>
</xsl:template>
<xsl:template match="comment()">
<li>
<xsl:value-of select="."/>
</li>
</xsl:template>
Related
I'm learning on the fly, and I have commented C# code with /// that generates xml after:
csc Class1.cs /out:Class1Docs /rescurse:*.cs /doc:Class1Doc.xml
My xsl file (the relevant part) is like so:
<xsl:for-each select="doc">
<br>
<xsl:value-of select="members/member"/>
</br>
<br>
<xsl:value-of select="summary"/>
</br>
</xsl:for-each>
</body>
</html>
</xsl:template>
The problem is that I need to output the member, summary, params, and return value.
I only get the 'member/member' returned:
Class1 Class
How do i select the xsl:value of for each tag ?
My xsl file (the relevant part) is
like so:
<xsl:for-each select="doc">
<br>
<xsl:value-of select="members/member"/
</br>
<br>
<xsl:value-of select="summary"/>
</br>
</xsl:for-each>
</body>
</html>
</xsl:template>
This is badly malformed XML!
Let's think that the relevant, well-formed portion is:
<xsl:for-each select="doc">
<br>
<xsl:value-of select="members/member"/>
</br>
<br>
<xsl:value-of select="summary"/>
</br>
</xsl:for-each>
There are many problems with this code:
AFAIK the (x)HTML element br should have no content. Maybe you wanted:
<xsl:value-of select="members/member"/>
The <xsl:value-of> instruction creates a text node that contains the string value of the first node only, that is specified in the XPath expression in the select attribute.
Probably you wanted:
<xsl:copy-of select="members/member/text()"/>
.3. Specifying all literal result elements and using <xsl:for-each> within a single template is not a good XSLT programming practice. It is recommended to use more templates and correspondingly, <xsl:apply-templates> instead of <xsl:for-each>.
I can't really post the whole XML example because it's internal info
Then it's easy enough to provide an example that exhibits all the necessary properties of the real data, surely? You can't expect people to help you with one hand tied behind their backs.
Like other responders, I'm guessing, but my guess is that you failed to realise that in XSLT 1.0, the xsl:value-of instruction only outputs the string value of the first node in the sequence. If for some reason you can't move to XSLT 2.0, you need to put the xsl:value-of inside an xsl:for-each or xsl:apply-templates loop.
I'm writing XSL and I want to make comments throughout the code that will be stripped when it's processed, like PHP, however I'm not sure how.
I'm aware of the comment object, but it prints out an HTML comment when processed. :\
<xsl:comment>comment</xsl:comment>
You use standard XML comments:
<!-- Comment -->
These are not processed by the XSLT transformer.
Just make sure that you put your <!-- comments --> AFTER the opening XML declaration (if you use one, which you really don't need):
BREAKS:
<!-- a comment -->
<?xml version="1.0"?>
WORKS:
<?xml version="1.0"?>
<!-- a comment -->
I scratched my head on this same issue for a bit while debugging someone else's XSLT... seems obvious, but easily overlooked.
Note that white space on either side of the comments can end up in the output stream, depending on your XSLT processor and its settings for handling white-space. If this is an issue for your output, make sure the comment is bracketed by xslt tags.
EG
<xsl:for-each select="someTag">
<xsl:text>"</xsl:text>
<!-- output the id -->
<xsl:value-of select="#id"/>
<xsl:text>"</xsl:text>
</xsl:for-each>
Will output " someTagID" (the indent tab/spaces in front of the comment tag are output).
To remove, either unindent it flush with left margin, or bracket it like
<xsl:text>"</xsl:text><!-- output the id --><xsl:value-of select="#id"/>
This is the way to do it in order to create a comment node that won't be displayed in html
<xsl:comment>
<!-- Content:template -->
</xsl:comment>
Sure. Read http://www.w3.org/TR/xslt#built-in-rule and then it should be apparent why this simple stylesheet will (well, should) do what you want:
<?xml version="1.0"?>
<xsl:stylesheet xmlns="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="comment()">
<xsl:copy/>
</xsl:template>
<xsl:template match="text()|#*"/>
</xsl:stylesheet>
Try :
<xsl:template match="/">
<xsl:for-each select="//comment()">
<SRC_COMMENT>
<xsl:value-of select="."/>
</SRC_COMMENT>
</xsl:for-each>
</xsl:template>
or use a <xsl:comment ...> instruction for a more literal duplication of the source document content in place of my <SRC_COMMENT> tag.
I need to say; I'm pretty green in xslt so, most likely, that's the main problem; nonetheless been on it for hours and can't get it.
I want to fill a column on my main template with the 5 most recent newsitems. These newsitems should be shown regardless of the currentpage.
I've tried this:
<xsl:template match="/">
<xsl:for-each select="umbraco.library:GetXmlNodeById(1075)/child::node">
<p>
<strong>
<xsl:value-of select="header"/>
</strong>
</p>
</xsl:for-each>
</xsl:template>
Where, at the moment, 1075 is my News template. Ive tried it with just: GetXmlNodeById(1076)/node (where 1076) is my NewsItem template. I've tried it with the node-Id's from the content-tree, but no luck..
Anyone able to help me out here? Am stuck and I've searched high and low on Google, the forums and documentation, but I'm most likely missing something vital here. TIA!
P.S. Using Umbraco 4.5 BTW
This should output current and child nodes.
<xsl:copy-of select="umbraco.library:GetXmlNodeById(1075)"/>
In Umbraco 4.5 the schema has changed, from /node[#nodeTypeAlias='News'] to /News [#isDoc]
http://blog.leekelleher.com/2010/04/02/working-with-xslt-using-new-xml-schema-in-umbraco-4-1/
So your xslt should look like
<xsl:template match="/">
<ul>
<xsl:for-each select="umbraco.library:GetXmlNodeById(1075)/News [#isDoc]">
<li><xsl:value-of select="#nodeName"/></li>
</xsl:for-each>
</ul>
</xsl:template>
I've got some XML elements with a number attached as more are available.
Such as this:
<Images>
<Image1>C:\Path\To\AnImage</Image1>
<Image2>C:\Path\To\AnotherImage</Image2>
</Images>
The amount of Images in each XML doc is variable. How can I make sure that my XSL file will show all elements inside the tag?
I also want to put each of the strings inside each ImageX tag inside a Img src="stringfromxmlelement" with XSL? Is this possible?
Tony
<xsl:template match="Images/*[starts-with(name(),'Image']">
<img src="{.}" />
</xsl:template>
BTW, perhaps you can't change the XML tag names, but it would better to name the inner tags as Image rather than ImageX, which is probably unneccesary.
I'd try something along these lines:
<xsl:template match="Images">
<xsl:for-each select="*">
<img src="{text()}" />
</xsl:for-each>
</xsl:template>
I am trying to create hyperlinks using XML information and XSLT templates. Here is the XML source.
<smartText>
Among individual stocks, the top percentage gainers in the S. and P. 500 are
<smartTextLink smartTextRic="http://investing.domain.com/research/stocks/snapshot
/snapshot.asp?ric=HBAN.O">Huntington Bancshares Inc</smartTextLink>
and
<smartTextLink smartTextRic="http://investing.domain.com/research/stocks/snapshot
/snapshot.asp?ric=EK">Eastman Kodak Co</smartTextLink>
.
</smartText>
I want the output to look like this, with the company names being hyperlinks based on the "smartTextLink" tags in the Xml.
Among individual stocks, the top percentage gainers in the S.&P. 500 are Eastman Kodak Co and Huntington Bancshares Inc.
Here are the templates that I am using right now. I can get the text to display, but not the hyperlinks.
<xsl:template match="smartText">
<p class="smartText">
<xsl:apply-templates select="child::node()" />
</p>
</xsl:template>
<xsl:template match="smartTextLink">
<a>
<xsl:apply-templates select="child::node()" />
<xsl:attribute name="href">
<xsl:value-of select="#smartTextRic"/>
</xsl:attribute>
</a>
</xsl:template>
I have tried multiple variations to try to get the hyperlinks to work correctly. I am thinking that the template match="smartTextLink" is not being instantiated for some reason. Does anyone have any ideas on how I can make this work?
EDIT: After reviewing some of the answers, it is still not working in my overall application.
I am calling the smartText template from within my main template
using the following statement...
<xsl:value-of select="marketSummaryModuleData/smartText"/>
Could this also be a part of the problem?
Thank you
Shane
Either move the xsl:attribute before any children, or use an attribute value template.
<xsl:template match="smartTextLink">
<a href="{#smartTextRic}">
<xsl:apply-templates/>
</a>
</xsl:template>
From the creating attributes section of the XSLT 1 spec:
The following are all errors:
Adding an attribute to an element after children have been added to it; implementations may either signal the error or ignore the attribute.
Try this - worked for me:
<xsl:template match="smartText">
<p class="smartText">
<xsl:apply-templates/>
</p>
</xsl:template>
<xsl:template match="smartTextLink">
<a>
<xsl:attribute name="href">
<xsl:value-of select="#smartTextRic"/>
</xsl:attribute>
<xsl:value-of select="text()"/>
</a>
</xsl:template>
Trick is - <xsl:attribute> first, before you do any other processing.
Marc