Reputation: 3498
I'm playing around with XML and XSL. I have an XMLfile that looks somewhat like this:
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="/_xslt/xslt_terms.xsl" type="text/xsl" ?>
<terms>
<term><p>Use of Website</p>
<term>
<term><p>wording here</p></term>
<term><p>more words!</p></term>
</term>
<term><p>serious words</p></term>
</terms>
and an XSL file that looks like
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml" >
<xsl:template match="term">
<xsl:number level="multiple" format="1. "/>
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
The output should display like
1. Use of Website
1.1.
1.1.1. wording here
1.1.2. more words
1.2. serious words
but when i run
<cfoutput>
<cffile action="read"
file="#application.sPath#_xslt/xslt_terms.xsl"
variable="variables.xmltrans">
<cfset variables.xmldoc = XmlParse("#application.sPath#_templates/_ajax/_terms/xml_terms.xml")>
#XMLTransform(variables.xmldoc, variables.xmltrans)#
</cfoutput>
i get a giant block of text with no line breaks. so it looks like:
1. Use of Website 1.1. 1.1.1. wording here 1.1.2. more words 1.2. serious words
As i say, this is the first time i'm playing around with XML and XSL since.. a long time, so it's likely i've missed something
EDIT
I found some code to help which nearly does the job. I've changed my xml to remove all <p>
tags, and i've changed my xsl file to read:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="term">
<p>
<xsl:number format="1." level="multiple"/>
<xsl:apply-templates select="@*|node()"/>
</p>
</xsl:template>
This nearly does it, but i'm losing the indentation, is there anything i can do to make it indented like above?
Upvotes: 1
Views: 222
Reputation: 167696
If you can make sure that the complete HTML document your XSLT output is injected in can include some CSS then I would suggest to create a HTML ordered, nested list where the numbers are done with CSS:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:strip-space elements="*"/>
<xsl:output method="html" indent="yes" version="5.0"/>
<xsl:template match="/">
<html>
<head>
<title>list test</title>
<style>
ol.nested { counter-reset: section; list-style-type: none; }
ol.nested li { counter-increment: section; }
ol.nested li:before { content: counters(section, ".") ". "; }
</style>
</head>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="terms[term]">
<ol class="nested">
<xsl:apply-templates/>
</ol>
</xsl:template>
<xsl:template match="term">
<li>
<xsl:apply-templates select="node()[not(self::term)]"/>
<xsl:if test="term">
<ol class="nested">
<xsl:apply-templates select="term"/>
</ol>
</xsl:if>
</li>
</xsl:template>
</xsl:stylesheet>
With the input XML being
<?xml-stylesheet type="text/xsl" href="sheet.xsl"?>
<terms>
<term><p>Use of Website</p>
<term>
<term><p>wording here</p></term>
<term><p>more words!</p></term>
</term>
<term><p>serious words</p></term>
</term>
</terms>
modern browsers will render that as a nested listed with the counting you want.
If you want to create the numbers with XSLT then I would still create a HTML list as the HTML needs to be structured:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:strip-space elements="*"/>
<xsl:output method="html" indent="yes" version="5.0"/>
<xsl:template match="terms[term]">
<ol style="list-style-type: none;">
<xsl:apply-templates/>
</ol>
</xsl:template>
<xsl:template match="term">
<li><xsl:number level="multiple" format="1. "/>
<xsl:apply-templates select="node()[not(self::term)]"/>
<xsl:if test="term">
<ol style="list-style-type: none;">
<xsl:apply-templates select="term"/>
</ol>
</xsl:if>
</li>
</xsl:template>
</xsl:stylesheet>
Now when applied to the input
<?xml-stylesheet type="text/xsl" href="sheet.xsl"?>
<terms>
<term><p>Use of Website</p>
<term>
<term><p>wording here</p></term>
<term><p>more words!</p></term>
</term>
<term><p>serious words</p></term>
</term>
</terms>
you get the numbering you want.
Upvotes: 1