tags:

views:

587

answers:

6

What are the principles and patterns that go into writing effective XSLT?

When I say "effective" I mean that it is

  1. Well-structured and readable
  2. Simple, concise
  3. Efficient (i.e. has good performance)

In short, I'm looking for the best practices for XSLT.

I've already seen the question regarding efficiency, but efficient code loses its value if you can't understand what it's doing.

+5  A: 

Best practice 1 : use templates in stead of < xsl:for-each > whenever you can (which is 99% of the cases)

(may I add MAINTAINABILITY as extra ingredient in the best practices, imho even the most important one)

For understanding xsl you realy need a bit of practice.
Not understanding what sth. is doing is very relative of course.

That goes doube for XSLT, since the xsl:for-each construct tends to be

  • more readable

for a novice, but is in fact

  • less structured,
  • less simple,
  • less concise and
  • a lot less maintainable

than templates, and only

  • equaly readable (at best!!) for so. with a minimum of template experience.

NEVER, EVER USE THE < xsl:for-each > ELEMENT!

I admit, the title is somewhat exaggerated, there do exist, I've been told, cases in which a "xsl for each" can have it's merits, but those cases are very, very rare.

I once had to come up with a fairly complicated xml/xslt client site in less than a week, and used the for-each element all over the place. Now, several years later and, sort of, wiser, I took my time and rewrote the initial code, using only templates. The code now is much much cleaner and more adaptable.

Either you know this, or either you should : < xsl:template > and < xsl: apply-templates> are almost always the way to go. If you are xsl-ing, and you don't fully understand these tags, stop your work now, learn them, get a aha-erlebnis, and continue your work a as a reborn (wo)man.

Peter
I tend to think of maintainablility as a product being simple, concise, well-structured, and readable. What am I missing?
Peter Dolberg
maintainability also depends on flexibility.
Jimmy
sure, your point?
Peter
Actually, there *are* cases where one *must* use <xsl:for-each> !
Dimitre Novatchev
@Dimitre, of course! That's why I stated : I admit, the title is somewhat exaggerated, there do exist, I've been told, cases in which a "xsl for each" can have it's merits, but those cases are very, very rare.
Peter
+1  A: 

For readability's sake, I use the xsl:template tag. It is very concise and simple to use. It is simple to pass parameters to a template. This technique is called encapsulation and is one of the foundations of good programming.

harley.333
But in what situations do you use the xsl:template tag instead of something else? I see that usnig it instead of xslfor-each is a good idea. Are there any other situations?
Peter Dolberg
Often times, I use a template to simply encapsulate a bit of functionality. Being so verbose, XSLT files get very long very fast. By chopping them into smaller templates, I find the files easier to maintain and debug. If you've got a loop, that's an obvious candidate for a template.
harley.333
+5  A: 
Dimitre Novatchev
A: 

Simple, concise

I just want to say that XSLT wasn't designed to be anything like as concise as other programming languages you might be familiar with, and to strive too hard for that might be going against the grain of the language.

AmbroseChapel
Valid point. XSLT is annoyingly verbose, especially so because it is XML rather than a simple language. For that reason I favor XQuery for a lot of XML-based work.When I said simple and concise, I meant RELATIVELY concise. That is, as concise as XSLT can be.
Peter Dolberg
+2  A: 

File issues

1. A lot of small files are better than a few large ones.

Split you hamburger.xsl into i-bread.xsl and i-beef.xsl.

2. Prefix included/imported files with ‘i-’.

It serves as an indicator that file shoud be edited with caution, as you can break functionality of importing/including files. Check them before committing changes.

3. Never include/import an unprefixed file.

If you want to make a cheeseburger.xsl, do not include the hamburger.xsl. Instead, include i-bread.xsl, i-beef.xsl and newly created i-cheese.xsl.

Azat Razetdinov
+2  A: 

I think that a good way to answer this question would to approach it from the other side. What practices make XSLT ineffective, and why?

Some of the things that I've seen that result in ineffective XSLT:

  1. Overuse of for-each. Everyone's said it; I'm saying it again. I find that for-each is often a sign of the developer trying to employ traditional programming techniques in a declarative language.

  2. Underutilizing XPath. A lot of bad XSLT I've seen exists purely because the developer didn't understand predicates, axis specifiers, position(), and current(), and so he implemented logic using XSLT constructs instead.

  3. Underutilizing metadata. You can sometimes eliminate an enormous amount of XSLT by providing your transform with metadata.

  4. Underutilizing pre-processing. If, for instance, an XML document contains data that has to be parsed using XSLT string manipulation, it's often much simpler to do all of the parsing outside of XSLT and either add the parsed results to the XML or pass the parsed results as an argument to the transform. I've seen some remarkably unmaintainable XSLT implementing business logic that would be trivial to implement in C# or Python.

The biggest problem that I'm running into in my own XSLT world (I have several 3,000+ line transforms that I'm maintaining) is dead code. I'm certain that there are templates in my transforms that will never be used again, because the conditions they're testing for will never arise again. There's no way to determine programmatically if something like <xsl:template match="SomeField[contains(., "some value")]> is alive or dead, because it's contingent on something that metadata can't tell you.

Robert Rossney
Hi Robert, one way to minimize dead code is to use a library of functions/templates, such as FXSL. Then probably, you'd never have to write a 3000+ line transformation. One of the most comlex stylesheet I have ever written -- a parser for XPath 2.0 is just 657 lines. Of course, many FXSL funcs. used
Dimitre Novatchev
I do use template libraries. The problem I'm having is different. If I stop using the "Foo" element in my XML, nothing tells me to remove its matching template from my XSLT.
Robert Rossney