XSLT for Dummies

 
Chapter 11 - XPath Data Types and Functions
XSLT For Dummies
by Richard Wagner
Hungry Minds 2002
  

So much of XSLT is based on pushing text from one place to another and transforming it along the way. Therefore, having functions that can manipulate and transform strings can be a valuable tool for you as an XSLT stylesheet author. This section covers the functions available for string manipulation.

Extracting strings from strings

XPath has three functions that help you extract a string from a larger string: substring-before () , substring-after() , and substring() .

The syntax for the substring-before() and syntax-after() functions are:

string substring-before(source, str) string substring-after(source, str)

substring-before() returns the portion of source that comes before the first occurrence of str . If str is not found, then the result is an empty string. On the other hand, the substring-after() function returns the portion of source that comes after the first occurrence of str . It too returns an empty string if str is not found in the source .

The following example uses substring-before() to test whether or not the features child element includes Soup before the first comma. If so, then text is added to the result document. The substring-after() function is used to list everything else that follows the Soup , string:

<xsl:template match="entree"> <xsl:if test="substring-before(features, ',') = 'Soup'"> Soup is offered with <xsl:value-of select="@name"/> Also offered are: <xsl:value-of select="substring- after(features, 'Soup,')"/> </xsl:if> </xsl:template>

The results are :

Soup is offered with Filet Mig's None Also offered are: Vegetables, Baked Potato, and Dessert Soup is offered with Chicken Parmashaun Also offered are: Pasta, Baked Potato, and Dessert Soup is offered with Jerk Chicken Also offered are: Vegetables, and Dessert Soup is offered with Gusto Spaghetti Also offered are: Salad, and Dessert

You use the substring() function to get a string buried inside another string. The function has the following syntax:

string substring(source, start [, length])

The substring() function returns the substring of source beginning at the start position and having a length of length . If length is not specified, then it returns the remainder of the string. The following example extracts a substring from each description, starting at the position 5 and returning 3 characters :

<xsl:template match="entree"> <xsl:value-of select="substring(description, 5, 3)"/> </xsl:template>

The result is:

ken mas awa att lic fam

Searching and replacing text

You can use the translate() function to search and replace characters within a string. The syntax for the function is:

string translate(source, searchstr, replacestr)

searchstr specifies a string of characters that the translate() function looks for inside source . When each character is encountered , the character at the same position in replacestr replaces the original character.

For example, suppose you want to change all the text of the entree name to uppercase. To do so, I can create two variables : lower contains an all lowercase alphabet, and upper contains uppercase characters of the alphabet. As an xsl:for-each instruction runs through each of the entrees, the translate() function is used to map all the lowercase characters in the entrees name to the corresponding uppercase character:

<xsl:variable name="lower">abcdefghijklmnopqrstuvwxzyz</xsl: variable> <xsl:variable name="upper">ABCDEFGHIJKLMNOPQRSTUVWXYZ</xsl: variable> <xsl:template match="menu"> <xsl:for-each select="entree"> <xsl:value-of select="translate(@name, $lower, $upper)"/><xsl:text> </xsl:text> </xsl:for-each> </xsl:template>

The result is shown here:

SUNBURNT CHICKEN FILET MIG'S NONE CHICKEN PARMASHAUN EGGS BENELUX JERK CHICKEN GUSTO SPAGHETTI

 Remember   Remember that the translate() function is used to search and replace individual characters, not strings.

Testing strings

You can test the contents of a string to check and see if another string is inside it with the contains() and starts-with () functions. The syntax for these functions is:

boolean contains(source, str) boolean starts-with(source, str)

The contains() function returns true if str is found inside source . If not, then false is returned. starts-with() returns true if str is located at the start of the source string and false if not.

I use the contains() function in the following example to test for the presence of words in the entrees name. Based on the result of these evaluations, I add the entree into the appropriate category name:

<xsl:template match="entree"> <entree> <name><xsl:value-of select="@name"/></name> <category> <xsl:choose> <xsl:when test="contains(@name, 'Chicken')">Chicken</xsl:when> <xsl:when test="contains(@name, 'Spaghetti')">Italiano</xsl:when> <xsl:when test="contains(@name, 'Filet')">Beef</xsl:when> <xsl:otherwise>Other</xsl:otherwise> </xsl:choose> </category> </entree> </xsl:template>

The results follow:

<entree> <name>Sunburnt Chicken</name> <category>Chicken</category> </entree> <entree> <name>Filet Mig's None</name> <category>Beef</category> </entree> <entree> <name>Chicken Parmashaun</name> <category>Chicken</category> </entree> <entree> <name>Eggs Benelux</name> <category>Other</category> </entree> <entree> <name>Jerk Chicken</name> <category>Chicken</category> </entree> <entree> <name>Gusto Spaghetti</name> <category>Italiano</category> </entree>

Getting the length of a string

The string-length () function returns just what youd expect from a name like that: the length of a string. It looks like:

number string-length([string])

The example that follows uses string-length() to evaluate the size of the description element. If it is over 90 characters in length, it is flagged in the result document as being too long:

<xsl:template match="entree"> ============================================== <xsl:value-of select="@name"/>'s description: ============================================== "<xsl:value-of select="description"/><xsl:text>" </xsl:text> <xsl:if test="string-length(description) &gt; 90"> **** Hey there, Tex, this description is too long (<xsl:value-of select="string- length(description)"/> chars). Please shorten. *** </xsl:if> </xsl:template>

When the menu.xml (refer to Listing 11-1) is applied using this template rule, the output is:

============================================== Sunburnt Chicken's description: ============================================== "Chicken prepared so hot by our master chef Georgio Faucher, you'll need a gallon of soda to wash it down. Bring sunscreen!" ============================================== Filet Mig's None's description: ============================================== "Our master chef Mig prepares a uniquely no-fat filet mignon. You won't believe how great it tastes!" **** Hey there, Tex, this description is too long (99 chars). Please shorten. *** ============================================== Chicken Parmashaun's description: ============================================== "Our award-winning Chicken Parmesan prepared especially for you by our master chef Shaun." ============================================== Eggs Benelux's description: ============================================== "No matter the time of day, enjoy our scrumptious breakfast cooked by our famous Belgian and Dutch master chefs." **** Hey there, Tex, this description is too long (110 chars). Please shorten. *** ============================================== Jerk Chicken's description: ============================================== "A delicious hot Jamaican dish prepared by our most obnoxious master chef." ============================================== Gusto Spaghetti's description: ============================================== "Our famous master chef Boyd Ardee prepares a succulent dish of spaghetti with zesty gusto!"

In this example, two of the descriptions had a string length of over 90 characters and were flagged.

Concatenating a string

To combine several smaller strings into a whopping big string, you can use the concat() function:

string concat(string1, string2, [string3,])

This function combines string1 with string2 and as many other strings as you wish and returns them as a single concatenated string.

I use the concat() function in the following template rule to assemble a sentence out of literal text, an attribute value, and the string value of an element:

<xsl:template match="entree"> <xsl:value-of select="concat('The ', @name, ' entree has ', fatgrams, ' grams of fat.')"/> </xsl:template>

The result is:

The Sunburnt Chicken entree has 23 grams of fat. The Filet Mig's None entree has 0 grams of fat. The Chicken Parmashaun entree has 20 grams of fat. The Eggs Benelux entree has 35 grams of fat. The Jerk Chicken entree has 5 grams of fat. The Gusto Spaghetti entree has 55 grams of fat.

Trimming whitespace from strings

When you work with strings, you may frequently come across a situation in which whitespace is padded onto the beginning or end of a string you are using. The normalize-space() function is used to remove these unwanted whitespace areas in your string:

string normalize-space([string])

The returned string has been stripped of leading and trailing whitespace as well as replacing multiple whitespace characters with a single whitespace character inside of the string.

To demonstrate , the normalize-space() function is useful to clean up the substring-after() example earlier in the chapter. Note the extra whitespace in the following section from its result document (before Vegetables ):

Soup is offered with Filet Mig's None Also offered are: Vegetables, Baked Potato, and Dessert

Putting a normalize-space() inside that template helps clean up the result by removing this extra space:

<xsl:template match="entree"> <xsl:if test="substring-before(features, ',') = 'Soup'"> Soup is offered with <xsl:value-of select="@name"/> Also offered are: <xsl:value-of select="normalize- space(substring-after(features, 'Soup,'))"/> </xsl:if> </xsl:template>

The trimmed results are:

Soup is offered with Filet Mig's None Also offered are: Vegetables, Baked Potato, and Dessert Soup is offered with Chicken Parmashaun Also offered are: Pasta, Baked Potato, and Dessert Soup is offered with Jerk Chicken Also offered are: Vegetables, and Dessert Soup is offered with Gusto Spaghetti Also offered are: Salad, and Dessert

Converting an object into a string

To convert a node, number, or boolean value to a string, use the string() function:

string string(object)

A boolean value of false is converted to the string 'false' , while true becomes 'true' . A number becomes a string representation of the numeric value. A node returns its string value, while a nodeset returns the string value of the first node.

For example, the following boolean value

He answered: <xsl:value-of select="string(false())"/>

Becomes:

He answered: false

  
 
 
2000-2002    Feedback

Категории