ASPN ActiveState Programmer Network  
ActiveState, a division of Sophos
/ Home / Perl / PHP / Python / Tcl / XSLT /
/ Safari / My ASPN /
Cookbooks | Documentation | Mailing Lists | Modules | News Feeds | Products | User Groups
Submit Recipe
My Recipes

All Recipes
All Cookbooks


View by Category

Title: Tokenize strings and tabulate
Submitter: Nick Toze (other recipes)
Last Updated: 2003/03/17
Version no: 1.0
Category: String manipulation

 

Not Rated yet


Description:

Tokenizes strings into result tree fragments then processes those fragments to produce a table. Works with mozilla 1+ (which allows direct processing of result tree fragments) and with IE6 (with which it uses msxsl:node-set() to enable the fragment processing).

Source: Text Source

---- Test file

<?xml version="1.0"?>
<?xml-stylesheet href="tabulate.xsl" type="text/xsl"?>
<coords>
X value,Y value,Z value
1,3,5
2,1,6
4,5,2
9,3,7
13,7,3
</coords>


----- XSL file (tabulate.xsl)

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:msxsl="urn:schemas-microsoft-com:xslt">

	<xsl:template match="/">
		<html>
			<body>
				<xsl:call-template name="result_table">
					<xsl:with-param name="result_nodes" select="/coords"/>
				</xsl:call-template>
			</body>
		</html>
	</xsl:template>

	<xsl:template name="result_table">
		<xsl:param name="result_nodes"/>
		<xsl:variable name="results">
			<xsl:call-template name="split-string">
				<xsl:with-param name="all">
					<text>
						<xsl:value-of select="normalize-space(translate($result_nodes,' ','_'))"/>
					</text>
				</xsl:with-param>
				<xsl:with-param name="seperator" select="' '"/>
			</xsl:call-template>
		</xsl:variable>
		<table border="1">
			<xsl:choose>
				<xsl:when test="function-available('msxsl:node-set')">
					<xsl:variable name="results_index_star" select="msxsl:node-set($results)/index/*"/>
					<xsl:call-template name="make_rows">
						<xsl:with-param name="rows" select="$results_index_star"/>
					</xsl:call-template>
				</xsl:when>
				<xsl:otherwise>
					<xsl:call-template name="make_rows">
						<xsl:with-param name="rows" select="$results/index/*"/>
					</xsl:call-template>
				</xsl:otherwise>
			</xsl:choose>
		</table>
	</xsl:template>

	<xsl:template name="make_rows">
		<xsl:param name="rows"/>
		<xsl:for-each select="$rows">
			<xsl:variable name="results_row">
				<xsl:call-template name="split-string">
					<xsl:with-param name="all">
						<text>
							<xsl:value-of select="."/>
						</text>
					</xsl:with-param>
					<xsl:with-param name="seperator" select="','"/>
				</xsl:call-template>
			</xsl:variable>
			<tr>
				<xsl:choose>
					<xsl:when test="function-available('msxsl:node-set')">
						<xsl:variable name="results_row_index_star" select="msxsl:node-set($results_row)/index/*"/>
						<xsl:call-template name="make_a_row">
							<xsl:with-param name="row" select="$results_row_index_star"/>
						</xsl:call-template>
					</xsl:when>
					<xsl:otherwise>
						<xsl:call-template name="make_a_row">
							<xsl:with-param name="row" select="$results_row/index/*"/>
						</xsl:call-template>
					</xsl:otherwise>
				</xsl:choose>
			</tr>
		</xsl:for-each>
	</xsl:template>

	<xsl:template name="make_a_row">
		<xsl:param name="row"/>
		<xsl:for-each select="$row">
			<td>
				<xsl:value-of select="."/>
			</td>
		</xsl:for-each>
	</xsl:template>

	<!--
		Parameters: all: a whitespace-separated string, wrapped by a <text> element,
			plus optionally an initial index wrapped by an <index> element
		Output: an <index> element containing <w> elements
	-->
	<xsl:template name="split-string">
		<xsl:param name="all"/>
		<xsl:param name="seperator"/>
		<xsl:choose>
			<xsl:when test="function-available('msxsl:node-set')">
				<xsl:variable name="all_text" select="msxsl:node-set($all)/text"/>
				<xsl:variable name="all_index_star" select="msxsl:node-set($all)/index/*"/>
				<xsl:call-template name="split-string-impl">
					<xsl:with-param name="all" select="$all"/>
					<xsl:with-param name="seperator" select="$seperator"/>
					<xsl:with-param name="all_text" select="$all_text"/>
					<xsl:with-param name="all_index_star" select="$all_index_star"/>
				</xsl:call-template>
			</xsl:when>
			<xsl:otherwise>
				<xsl:variable name="all_text" select="$all/text"/>
				<xsl:variable name="all_index_star" select="$all/index/*"/>
				<xsl:call-template name="split-string-impl">
					<xsl:with-param name="all" select="$all"/>
					<xsl:with-param name="seperator" select="$seperator"/>
					<xsl:with-param name="all_text" select="$all_text"/>
					<xsl:with-param name="all_index_star" select="$all_index_star"/>
				</xsl:call-template>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>

	<xsl:template name="split-string-impl">
		<xsl:param name="all"/>
		<xsl:param name="seperator"/>
		<xsl:param name="all_text"/>
		<xsl:param name="all_index_star"/>
		<xsl:variable name="first" select="substring-before($all_text,$seperator)"/>
		<xsl:choose>
			<xsl:when test="$first or substring-after($all_text,$seperator)">
				<xsl:call-template name="split-string">
					<xsl:with-param name="all">
						<text>
							<xsl:value-of select="substring-after($all_text,$seperator)"/>
						</text>
						<index>
							<xsl:copy-of select="$all_index_star"/>
							<xsl:text>
							</xsl:text>
							<w>
								<xsl:value-of select="$first"/>
							</w>
						</index>
					</xsl:with-param>
					<xsl:with-param name="seperator" select="$seperator"/>
				</xsl:call-template>
			</xsl:when>
			<xsl:otherwise>
				<index>
					<xsl:copy-of select="$all_index_star"/>
					<xsl:text>
					</xsl:text>
					<w>
						<xsl:value-of select="$all_text"/>
					</w>
				</index>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>

</xsl:stylesheet>

The license for this recipe is available here.

Discussion:

Issues:
For processing the result tree fragment it has a fall-through to directly accessing the result tree fragment which is illegal according to version 1 of the XSL spec (but is allowed in the unfinished version 2 of the spec). This works for Mozilla, don't know about other browsers.



Add comment

No comments.



Highest rated recipes:

1. Search and Replace

2. Generating a newline

3. Internationalization ...

4. Restricting processing ...

5. Result Pagination with ...

6. Fetching information ...

7. Getting text children of ...

8. Creating empty elements




Privacy Policy | Email Opt-out | Feedback | Syndication
© 2006 ActiveState Software Inc. All rights reserved.