<comment>
<content>
This is a really long string. It is really long because it contains plenty of characters.
The purpose of this exercise is to separate this content element into blocks containing
one hundred each
</content>
</comment>

I have the XML file above and I need to use XSLT to gather 10 characters at a time to be placed under the <content>. Example:

<content>
<group1>This is a </group1>
<group2>really lon</group2>
<group3>...</group3>
</content>

Anyone help would be greatly appreciated.

Recommended Answers

All 4 Replies

This is a pretty straight forward solution. (It's also exactly like another solution I posed a few days ago!) The idea here is that you have a recursive template.

The template is called with a couple parameters. The "string" is the input string that you want to divided up. The "separator" parameter is the length of string that you want to divided them by. The "groupnumber" isn't really needed, but it was used as part of the name of the elements so I could increment the element names.

The template is first invoked and passed the string you want "comment/content". If this input string is less than or equal to the separator length, it creates 1 element with that string and it's done. If not, It creates the first element, and put a string inside that element that starts at the beginning of the input string and grabs the first X characters, where X is the separator length. It then recursively call itself again, with new parameters. It increments the "groupnumber" by 1, keeps the dividing string the same, but the new input string is all the characters that are leftover after putting the first X characters in the element. This repeats recursively until the string that is left is less than the "separator" length.

Have fun. This wasn't heavily tested, so could have some bugs! :) Enjoy

XSLT

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:output method="xml" indent="yes" />

	<xsl:template match="/">
		<comment>
			<xsl:call-template name="groupstring">
				<xsl:with-param name="string" select="comment/content"/>
				<xsl:with-param name="separator" select="10"/>
				<xsl:with-param name="groupnumber" select="1"/>
			</xsl:call-template>
		</comment>
	</xsl:template>

	<xsl:template name="groupstring">
		<xsl:param name="string" select="''"/>
		<xsl:param name="separator" select="/.."/>
		<xsl:param name="groupnumber" select="1"/>

		<xsl:choose>
			<xsl:when test="string-length($string) &lt;= $separator">
				<xsl:element name="{concat('group',$groupnumber)}">
					<xsl:value-of select="$string"/>
				</xsl:element>
			</xsl:when>
			<xsl:otherwise>
				<xsl:element name="{concat('group',$groupnumber)}">
					<xsl:value-of select="substring($string, 1, $separator)"/>
				</xsl:element>
				<xsl:call-template name="groupstring">
					<xsl:with-param name="string" select="substring($string, $separator +1 , string-length($string))"/>
					<xsl:with-param name="groupnumber" select="$groupnumber + 1"/>
					<xsl:with-param name="separator" select="$separator"/>
				</xsl:call-template>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>
</xsl:stylesheet>

Output Document

<comment>
  <group1>This is a </group1>
  <group2>really lon</group2>
  <group3>g string. </group3>
  <group4>It is real</group4>
  <group5>ly long be</group5>
  <group6>cause it c</group6>
  <group7>ontains pl</group7>
  <group8>enty of ch</group8>
  <group9>aracters. </group9>
  <group10>The purpos</group10>
  <group11>e of this </group11>
  <group12>exercise i</group12>
  <group13>s to separ</group13>
  <group14>ate this c</group14>
  <group15>ontent ele</group15>
  <group16>ment into </group16>
  <group17>blocks con</group17>
  <group18>taining on</group18>
  <group19>e hundred </group19>
  <group20>each</group20>
</comment>

The XML file, when rendered in the browser comes up blank for me.

Not sure what to tell you... My XSLT works perfectly fine. When I input your document below, I get the output document that I produced. Either way, the logic for doing what you're trying to do in your transformation will be nearly identical. Recursive call template where you divide and pass the string back to itself.

<comment>
<content>This is a really long string. It is really long because it contains plenty of characters. The purpose of this exercise is to separate this content element into blocks containing one hundred each</content>
</comment>

Yeah got it working. Don't know why it wasn't showing before but it's OK now. Thanks for your help

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.