The Tao of Recursion: Named Templates in XSLT

The Tao of Recursion: Named Templates in XSLT

ascally Recursion
Extensible Stylesheet Language Transformations, or XSLT, allows you to transform XML documents into other XML documents using XSL. Using XSLT can be very trying, but it is, in fact, possible to do a great number of things with XSLT templates. However, to do so you have to understand that there is a fairly significant difference between recursive and non-recursive programming.

A programmer friend of mine once pointed out that any recursive problem, one where you call a routine using information generated by a previous iteration of that routine (and typically where the routine calls itself), can in fact be transformed into a non-recursive version of the same routine. I replied to that with the observation that this was like taking a novel, removing the binding, and then spreading the sheets end to end before reading them. You could do it, certainly, but you lose most of the benefits of having it in book form in the first place (at which point he threw the book at me).

XSLT is an uncomfortable language for a lot of people precisely because it almost forces you to think in a recursive manner. However, as an example, you can create a very simple XSLT template that effectively duplicates an entire document with surprisingly little code:

This routine is recursive?it essentially walks the tree of the XML document by moving to a node, copying that node, then applying the same template to any child element, any attribute or any text node. Of course, a stylesheet that returns the same XML as was passed in would be pretty useless, except for the fact that you can use this stylesheet exactly with additional templates to catch exceptions that you don’t want to just pass through.

For example, suppose that you had an XML document that contained a list of employees in your company, as shown in Listing 1. You can use a recursive approach to filter the XML so that only those employees who started in 1998 are listed. To do that, you could adapt the identity.xsl transform given above by creating a filter that will look at the date_started element of a given employee and compare the first four characters against ‘1998’. If this condition isn’t true, the node is simply not passed.

Think of the second template as being a short circuit that filters out information. In a similar manner, you can create another stylesheet that works off this one that will provide a cost of living increasing of 10% of salary for those employees who started in 1998.

While this would be a fairly simple script to write in procedural form, the approach would be different. There, the likely avenue of exploration would be to iterate through all the employees who match the date criteria, changing the salary when such a match is made, then copying the resulting node to an output node set. Ironically, to do this in XSLT requires a little more forethought, though not a lot:

XSLT templates are evaluated (all other things being equal) in reverse order from the way they are presented. Thus, both 1998 employees and other employees will match the first template, but only 1998 employees will match the second, and once a template is matched no other templates are applied. Now, it is likely that when you get employees by year, you will need to be able to work with more than just 1998. You can generalize the content by using parameters, which can be set more easily regardless of the XSLT processor that you’re using than attempting to set a date within a starts-with() function. This is shown in getEmployeesByDate.xsl:

		

This actually turns this script into a fairly high-powered function?it will return an XML document that gives only employees for a specific year. Additionally, for these employees, you could add or remove elements to the employee record.

Again, as an example, you may want to assign add a tag called that contains the value ‘yes’ if the employee is in Information Technologies and ‘no’ otherwise. This can be done as a simple variation off the previous script:

			yesno

In this case, the current contents of each employee’s record is duplicated, then the review tag is added, which contains the conditional test described earlier. The element in the second employee template serves to copy the element itself, which is why the needs to be within that block.

Named Templates
The statement takes the approach that each node chosen by the select statement will match some template somewhere else in the XSLT stylesheet (even if that node is the same template). However, in a number of cases, it makes a lot more sense to keep the action in the same template and work with the non-recursive case. The handles this situation.

In this case, the context?the node that is currently being acted on?changes from that of the current template to each of the nodes chosen in the select statement in turn, so long as that ‘for-each’ is in effect. This is one way of “flattening the hierarchy” and making the XSLT code less recursive. Thus, the code that handles the review of employees could be changed into a for-each paradigm:

yesno

This approach can make code that is more familiar to procedural programmer, but it often comes at the expense of flexibility in the code. To update the salary, for instance, you would actually need to set up an exception in the statement to handle the salary case.

‘For-each’ can also be a little misleading. Because it’s similar to the ‘for’ statement found in most procedural languages, ‘for-each’ can make people think that you can use it to create an indexed iterator?a value that increases (or decreases) by a specific amount after each iteration. A classic example of this is the FOR statement in Basic:

for i=0 to 255 step 1	print i,chr(i)next i

Unfortunately, such a construct doesn’t exist in XSLT. Part of this has to do with the fact that XSLT is a declarative language?the same variable cannot be declared with different values in the same scope. Another reason for this has to do with the fact that the classical template expects a match based upon an XPath context, which doesn’t work well in an indexed iterator model.

Suppose, however, that you could invoke a template by a specific name, rather than by a match condition. This actually has implications outside of just creating an iterator?there are any number of situations where the ability to create output based upon something other than context matching crops up.

For example, consider tables. A general routine to generate a table from a generic XML structure is a very common requirement, yet one of the problems that accompanies the creation of such tables is building column headers for the tables. You need to know the names of the columns ahead of time (making it difficult to generalize the routines). Or you need to content yourself with using XML element names for labels, which often means having odd cases and underscore characters in your output, a condition that is generally not acceptable either. However, a named template could simplify your code?by passing the element name as a parameter to such a template, the routine could convert the element name into a suitably formatted string.

Named templates are in fact a part of the XSLT specification, though sometimes they are not used as often as they should be. In a named template, the match attribute in a template is replaced with a name attribute instead, which contains the name of the template to be called. Named templates are parameterized?you can actually define one or more parameters for a named template in a similar manner to the way that you define parameters for a stylesheet.

A fairly simple case converter might make all lower case characters upper case and replace underscore characters with spaces. This template, “to_upper_case,” accepts one parameter, the expression to be converted, and returns the string with all characters converted to upper case:

		

The translate method here looks at each character in the passed expression, and if it finds the character in the second string (in this case, in the lower case characters), it matches it to the character in the third string (in this case, the upper case characters). Similarly, an underscore character is converted into a space, in the above expression.

This named template is invoked using the method, with each parameter assigned using the element. For example, the following code will convert “this_is_a_test” into “THIS IS A TEST”.

In this case the conversion is fairly simple, but you can also create more generalized routines that are considerably more complex. The change_case named template, as an example, can be used to convert any string entity into an uppercased entity (“AbcDef” becomes “abcdef”), a lowercased entity (“AbcDef becomes “abcdef”), or a mixed case entity. This last format relies on the use of a delimiter, such as an underscore character, to indicate which characters are converted into upper case. Thus, for the expression “line_item_number” (which may be the name of a given element in an invoice XML document), the mixed case result is “Line Item Number”. The change_case named template is shown in Listing 2.

Such a template can seem a little overwhelming, but it is also quite powerful. Instead of one parameter, change_case actually has five parameters:expr, to_case,replace_term, delimiter and result. The parameter to_case can take any one of “upper”, “lower”, “mixed”, or “none” (the last of which just returns the string as originally presented). The character or characters in replace_term (defaulting to the underscore character) are replaced by the contents of delimiter (which defaults to the space character).

The final parameter, “result,” illustrates the recursive nature of XSLT again. XSLT doesn’t have an intrinsic “replace” function, but it does have the means to split a string into two strings before or after a given delimiter. The change_case template uses this to walk from replace term to replace term in a string, accumulating the contents of one operation. If the routine hasn’t reached the end of the string, the change_case template calls itself, passing the reduced string as the new expression parameter and the processed result as the result parameter. Thus, “result” is actually used to maintain state within the change_case template.

Towards an XSLT Framework
There is no reason why either the replace term or the delimiter needs to be a single character, by the way. You could use exactly the same routine to replace a string in a text node with another string. Recognizing this, the same stylesheet defines a second function called “replace” that, in turn, calls change_case. The primary purpose for doing this is to create an alias that makes more sense for the replace operation. Thus,

will replace “You should use DOM to handle all of your XML programming needs” with “You should use XSLT to handle all of your XML programming needs”.

Note that the stylesheet contains no matches for the root node. These named templates are essentially designed to be called from other templates, so would more likely be imported and used indirectly. For example, the stylesheet in Listing 3 will create a table showing the employee columns, using the change_case routine as an imported template.

Named templates can prove addictive, by the way. For example, the table generation routines are fairly generic, and could themselves be adapted to create generic tables with mixed case headers. The create_table.xsl file located in Listing 4, contains a couple of templates that will turn any collection of records (such as the employees in the sample) into a table.

The create_table stylesheet takes a node set of records, creates the header for it, then iterates through each record matched to the “*” XPath expression. Note the use of the mode attribute here. Imported matching routines normally override the ones in the calling document, so there has to be a way to make sure that the “*” template will be matched only when called from change_case. The mode attribute lets you do just that?by placing a mode attribute with a given label on an apply-templates element, only those templates that have that same mode label will be matched.

This is a powerful concept, because it means that you can abstract many of the operations that you normally do in XSLT in named templates, then just import the templates that you actually need. For example, the following XSLT will now convert the employees XML structure into a table with mixed case headers.:

$	

See Table 1.

One of the problems with such generic filters is the ability to customize content. While you can go back to specifying all of the elements, you can also take a middle ground by creating a way to extend your model. In the recordTable.xsl file, for instance, the record_match mode template invokes a second mode, record_text_match, which defaults to just outputting the text of the current element. Since the imported template is considered to be part of the same scope as the invoking template, you can create a template that specifically matches the exception you’re trying to catch (here, it’s salary) and handle it as a special case.

The upshot of all of this is that you can create much simpler XSLT templates that can still be customized for your needs. As one of the common complaints about XSLT is its complexity, this means that your XSLT programmer can concentrate on designing specialized components, making the process of building XML oriented sites just that much easier.

devx-admin

devx-admin

Share the Post:
Bold Evolution

Intel’s Bold Comeback

Intel, a leading figure in the semiconductor industry, has underperformed in the stock market over the past five years, with shares dropping by 4% as

Semiconductor market

Semiconductor Slump: Rebound on the Horizon

In recent years, the semiconductor sector has faced a slump due to decreasing PC and smartphone sales, especially in 2022 and 2023. Nonetheless, as 2024

Learn Web Security

An Easy Way to Learn Web Security

The Web Security Academy has recently introduced new educational courses designed to offer a comprehensible and straightforward journey through the intricate realm of web security.

Military Drones Revolution

Military Drones: New Mobile Command Centers

The Air Force Special Operations Command (AFSOC) is currently working on a pioneering project that aims to transform MQ-9 Reaper drones into mobile command centers

Tech Partnership

US and Vietnam: The Next Tech Leaders?

The US and Vietnam have entered into a series of multi-billion-dollar business deals, marking a significant leap forward in their cooperation in vital sectors like

Bold Evolution

Intel’s Bold Comeback

Intel, a leading figure in the semiconductor industry, has underperformed in the stock market over the past five years, with shares dropping by 4% as opposed to the 176% return

Semiconductor market

Semiconductor Slump: Rebound on the Horizon

In recent years, the semiconductor sector has faced a slump due to decreasing PC and smartphone sales, especially in 2022 and 2023. Nonetheless, as 2024 approaches, the industry seems to

Elevated Content Deals

Elevate Your Content Creation with Amazing Deals

The latest Tech Deals cater to creators of different levels and budgets, featuring a variety of computer accessories and tools designed specifically for content creation. Enhance your technological setup with

Learn Web Security

An Easy Way to Learn Web Security

The Web Security Academy has recently introduced new educational courses designed to offer a comprehensible and straightforward journey through the intricate realm of web security. These carefully designed learning courses

Military Drones Revolution

Military Drones: New Mobile Command Centers

The Air Force Special Operations Command (AFSOC) is currently working on a pioneering project that aims to transform MQ-9 Reaper drones into mobile command centers to better manage smaller unmanned

Tech Partnership

US and Vietnam: The Next Tech Leaders?

The US and Vietnam have entered into a series of multi-billion-dollar business deals, marking a significant leap forward in their cooperation in vital sectors like artificial intelligence (AI), semiconductors, and

Huge Savings

Score Massive Savings on Portable Gaming

This week in tech bargains, a well-known firm has considerably reduced the price of its portable gaming device, cutting costs by as much as 20 percent, which matches the lowest

Cloudfare Protection

Unbreakable: Cloudflare One Data Protection Suite

Recently, Cloudflare introduced its One Data Protection Suite, an extensive collection of sophisticated security tools designed to protect data in various environments, including web, private, and SaaS applications. The suite

Drone Revolution

Cool Drone Tech Unveiled at London Event

At the DSEI defense event in London, Israeli defense firms exhibited cutting-edge drone technology featuring vertical-takeoff-and-landing (VTOL) abilities while launching two innovative systems that have already been acquired by clients.

2D Semiconductor Revolution

Disrupting Electronics with 2D Semiconductors

The rapid development in electronic devices has created an increasing demand for advanced semiconductors. While silicon has traditionally been the go-to material for such applications, it suffers from certain limitations.

Cisco Growth

Cisco Cuts Jobs To Optimize Growth

Tech giant Cisco Systems Inc. recently unveiled plans to reduce its workforce in two Californian cities, with the goal of optimizing the company’s cost structure. The company has decided to

FAA Authorization

FAA Approves Drone Deliveries

In a significant development for the US drone industry, drone delivery company Zipline has gained Federal Aviation Administration (FAA) authorization, permitting them to operate drones beyond the visual line of

Mortgage Rate Challenges

Prop-Tech Firms Face Mortgage Rate Challenges

The surge in mortgage rates and a subsequent decrease in home buying have presented challenges for prop-tech firms like Divvy Homes, a rent-to-own start-up company. With a previous valuation of

Lighthouse Updates

Microsoft 365 Lighthouse: Powerful Updates

Microsoft has introduced a new update to Microsoft 365 Lighthouse, which includes support for alerts and notifications. This update is designed to give Managed Service Providers (MSPs) increased control and

Website Lock

Mysterious Website Blockage Sparks Concern

Recently, visitors of a well-known resource website encountered a message blocking their access, resulting in disappointment and frustration among its users. While the reason for this limitation remains uncertain, specialists

AI Tool

Unleashing AI Power with Microsoft 365 Copilot

Microsoft has recently unveiled the initial list of Australian clients who will benefit from Microsoft 365 (M365) Copilot through the exclusive invitation-only global Early Access Program. Prominent organizations participating in

Microsoft Egnyte Collaboration

Microsoft and Egnyte Collaboration

Microsoft has revealed a collaboration with Egnyte, a prominent platform for content cooperation and governance, with the goal of improving real-time collaboration features within Microsoft 365 and Microsoft Teams. This

Best Laptops

Top Programming Laptops of 2023

In 2023, many developers prioritize finding the best laptop for programming, whether at home, in the workplace, or on the go. A high-performing, portable, and user-friendly laptop could significantly influence

Renaissance Gaming Magic

AI Unleashes A Gaming Renaissance

In recent times, artificial intelligence has achieved remarkable progress, with resources like ChatGPT becoming more sophisticated and readily available. Pietro Schirano, the design lead at Brex, has explored the capabilities

New Apple Watch

The New Apple Watch Ultra 2 is Awesome

Apple is making waves in the smartwatch market with the introduction of the highly anticipated Apple Watch Ultra 2. This revolutionary device promises exceptional performance, robust design, and a myriad

Truth Unveiling

Unveiling Truths in Bowen’s SMR Controversy

Tony Wood from the Grattan Institute has voiced his concerns over Climate and Energy Minister Chris Bowen’s critique of the Coalition’s support for small modular nuclear reactors (SMRs). Wood points

Avoiding Crisis

Racing to Defy Looming Financial Crisis

Chinese property developer Country Garden is facing a liquidity challenge as it approaches a deadline to pay $15 million in interest associated with an offshore bond. With a 30-day grace

Open-Source Development

Open-Source Software Development is King

The increasingly digital world has led to the emergence of open-source software as a critical factor in modern software development, with more than 70% of the infrastructure, products, and services

Home Savings

Sensational Savings on Smart Home Security

For a limited time only, Amazon is offering massive discounts on a variety of intelligent home devices, including products from its Ring security range. Running until October 2 or while

Apple Unleashed

A Deep Dive into the iPhone 15 Pro Max

Apple recently unveiled its groundbreaking iPhone 15 Pro and iPhone 15 Pro Max models, featuring a revolutionary design, extraordinary display technology, and unrivaled performance. These new models are the first