[xsl] Problem in making an html representation of xml document

Subject: [xsl] Problem in making an html representation of xml document
From: "Munna D" <munna@xxxxxxxxxx>
Date: Mon, 08 Mar 2004 12:06:33 -0500
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="'&#xA;'"/>
<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>&lt;?xml version='1.0'?&gt;</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(*)&gt;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>&#160;</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>&lt;?</xsl:text><xsl:value-of select="name()"/>
			<xsl:text>&#160;</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>?&gt;</xsl:text>
		</span>
	</xsl:template>
	
	<xsl:template match='//comment()'>				
		<span class='comment' style="color:#999999;">
			<xsl:text>&lt;--</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>--&gt;</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>&lt;</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>&gt;</xsl:text>
			</xsl:when>
			<xsl:otherwise>
				<xsl:text>&gt;</xsl:text><xsl:apply-templates/>
				<xsl:text>&lt;/</xsl:text><xsl:value-of select="name(.)"/>
				<xsl:text>&gt;</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) &lt;
	$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 &lt;= 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


Current Thread