I have just started learning XSLT, and was hoping that the members of this list
would help me with this problem:
I would like to create an exact replica of an xml document on a web page, ie,
an html page which presents the xml with original line breaks etc preserved,
but with line numbers (as you'd see if you viewed the file in a text-editor
such as Textpad) and additional formatting (so that I could add annotations --
images or links --next to specific elments).
I have appended my solution below, but if you use it to transform any xml
document, you will see there are a few problems:
(1) word-wrap works on text-only lines, but not on lines which have a mixture
of text, attribute and element nodes.
(2) I haven't yet found a way to correctly display line numbers, as they would
be displayed if the xml file was viewed on a line-numbering enabled text-editor.
(3) I'd ideally like to have the whole thing displayed neatly in a table at the
centre of the html page, but haven't figured out how to do this either.
Any suggestions would be extremely welcome -- I have recently started exploring
XSLT, and have a feeling I'm rather out of my depth here!
Many thanks,
Munna
--------------------------------------------------------
My stylesheet:
--------------------------------------------------------
<xsl:stylesheet
version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent='yes'/>
<xsl:variable name="EOL" select="'
'"/>
<xsl:variable name="BREAK" select="' '"/>
<xsl:template match="/">
<html>
<head>
<style>
body
{font-family:monospace;
font-size:small;}
div.msg
{background-color:yellow;}
.text
{color: black;
font-weight:bold
font-size:small}
pre { white-space: pre-wrap }
</style>
</head>
<body>
<pre>
<span class='pi' style="color:green;">
<xsl:text><?xml version='1.0'?></xsl:text>
</span>
<br/>
<xsl:apply-templates/>
</pre>
</body>
</html>
</xsl:template>
<xsl:template match='//*'>
<xsl:choose>
<xsl:when test='not(text() )'>
<span class='element'>
<xsl:call-template name='elementLayout' />
</span>
</xsl:when>
<xsl:when test='count(*)>1'>
<span class='element'>
<xsl:call-template name='elementLayout' />
</span>
</xsl:when>
<xsl:otherwise>
<span class='spanelement'>
<xsl:call-template name='elementLayout' />
</span>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match='@*'>
<xsl:text> </xsl:text>
<xsl:value-of select="name()"/>='<xsl:value-of select="."/>'
</xsl:template>
<xsl:template match='//processing-instruction()'>
<span class='pi' style="color:green;">
<xsl:text><?</xsl:text><xsl:value-of
select="name()"/>
<xsl:text> </xsl:text>
</span>
<xsl:variable name="output">
<xsl:call-template name="breakText">
<xsl:with-param name="strMsg" select="." />
<xsl:with-param name="numChars" select="120" />
</xsl:call-template>
</xsl:variable>
<span class='pi' style="color:green;">
<xsl:value-of select="$output" />
<xsl:text>?></xsl:text>
</span>
</xsl:template>
<xsl:template match='//comment()'>
<span class='comment' style="color:#999999;">
<xsl:text><--</xsl:text>
</span>
<xsl:variable name="output">
<xsl:call-template name="breakText">
<xsl:with-param name="strMsg" select="." />
<xsl:with-param name="numChars" select="120" />
</xsl:call-template>
</xsl:variable>
<span class='comment' style="color:#999999;">
<xsl:value-of select="$output" />
<xsl:text>--></xsl:text>
</span>
</xsl:template>
<xsl:template match='//text()'>
<xsl:variable name="output">
<xsl:call-template name="breakText">
<xsl:with-param name="strMsg" select="." />
<xsl:with-param name="numChars" select="120" />
</xsl:call-template>
</xsl:variable>
<span class="text" style="color:black;">
<xsl:value-of select="$output" />
</span>
</xsl:template>
<xsl:template name='elementLayout'>
<span class="tag" style="color:#CC3300;">
<xsl:text><</xsl:text>
<xsl:value-of select="name(.)"/>
</span>
<xsl:variable name="attlist">
<xsl:apply-templates select='@*'/>
</xsl:variable>
<xsl:variable name="output">
<xsl:call-template name="breakText">
<xsl:with-param name="strMsg" select="$attlist"
/>
<xsl:with-param name="numChars" select="100" />
</xsl:call-template>
</xsl:variable>
<span class="attlist" style="color:blue;">
<xsl:value-of select="$output" />
</span>
<span class="tag" style="color:#CC3300;">
<xsl:choose>
<xsl:when test='not( node() )'>
<xsl:text>/</xsl:text>
<xsl:text>></xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>></xsl:text><xsl:apply-templates/>
<xsl:text></</xsl:text><xsl:value-of
select="name(.)"/>
<xsl:text>></xsl:text>
</xsl:otherwise>
</xsl:choose>
</span>
</xsl:template>
<!--***********The word-wrap templates**********
http://florin.its.unimelb.edu.au/~bjdean/hypermail/ibmdevworks/2002.11/0143.html
IBM developerWorks XML Tip
5 November 2002
Vol. 2, Issue 44
Breaks msg into one or more lines.
Lines are broken at the numChars-th character, so lines
will have no more than (numChars-1) characters per line.
********************************************-->
<xsl:template name="breakText">
<xsl:param name="strMsg"/>
<xsl:param name="numChars"/>
<xsl:choose>
<xsl:when test="string-length($strMsg) <
$numChars">
<xsl:value-of select="concat($strMsg,' ')"/>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="strFirst">
<xsl:call-template
name="maxSubstringEndingWithBreak">
<xsl:with-param
name="strFragment"
select="substring($strMsg,1,$numChars)"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="strRest"
select="substring-after($strMsg,$strFirst)"/>
<xsl:value-of select="$strFirst"/>
<xsl:value-of select="$EOL"/>
<xsl:call-template name="breakText">
<xsl:with-param name="strMsg"
select="$strRest"/>
<xsl:with-param name="numChars"
select="$numChars"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="maxSubstringEndingWithBreak">
<xsl:param name="strFragment"/>
<xsl:variable name="len" select="string-length($strFragment)"/>
<xsl:choose>
<xsl:when test="len <= 1 or substring($strFragment,$len)=$BREAK
or contains($strFragment,$BREAK)=false">
<xsl:value-of select="$strFragment"/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="maxSubstringEndingWithBreak">
<xsl:with-param name="strFragment"
select="substring($strFragment, 1, $len - 1)"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!--********End of the word-wrap templates******-->
</xsl:stylesheet>
------------------------------------------------------------------------------------------
--
_______________________________________________
Get your free email from http://www.iname.com
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list