Wed 27 Sep 2006

Just a quick tip about xsl which I haven’t found anywhere else…

I wanted to generate some human (well me) readable XML using XSL and found that if you add xml:space=”preserve” to the opening tag, then, at least if you are using Xalan and Java to do the transformation, it will preserve the spaces between the tags in the XSL and you’ll get something more or less readable.

But then I tried using xsl:attribute to add attributes and I got the following error:
<br /> SystemId Unknown; Line #5; Column #101; Cannot add attribute x after child nodes or before an element is produced. Attribute will be ignored.<br />

The XSL I was using was of the form:

<point>
<xsl:attribute name="x"><xsl:value-of select="@period"/></xsl:attribute>
</point>

Without xml:space=”preserve” it works fine, but with it, I get the error. If I add the xml:space=”preserve” but put the xsl:attribute directly next to the point element (soThere are a some work arounds:</p>

  • Don’t put any space after the element and any xsl:attribute elements, you can put other tags (xsl:if for example), just not space.
  • Don’t use xml:space=”preserve”! You can still generate human readable XML by using xsl:text. Any space inside the xsl:text is preserved, including carriage-return/line-feed. So you can use that to format your XML–in fact you can do it more precisely, though perhaps at the risk of making your XSL more difficult to read.
  • Finally, I noticed that if you use xsl:include to include other xsl files, then you can have xml:preserve=”space” in some but not others. So, you might be able to get away with not including it in the sheets where you need to add the attributes.

Good luck