Jump to content

Macros in XSLT

michaelbailey's Photo
Posted Jan 23 2010 10:37 AM
3753 Views

I've spent 5 years working on this problem (well, not really - I implemented a post-transformation kludge, but it's been itching at me and just came to the forefront).

My problem is that I'm transforming from xml to xml, but need to add whitespace in one element. I've tried everything from preserve-space to enclosing whitespace in <xsl:text> tags, but somehow the Oracle XMLTransform() call, or something about the XMLElement() initialization, wipes whitespace out. My kludge was to add a '\' in the stylesheet every time I needed to prevent xslt from, say, stripping all my line breaks out of an empty text element.

Yesterday I found my way partway to a solution:

1) The element in question gets an xml:space="preserve"
2) The space is signified by <xsl:text>&#x0A;</xsl:text>, xsl:text>&#x09;</xsl:text>, etc. And no, just <xsl:text> </xsl:text> etc. did not work, almost like there are 2 levels of stripping going on.

My problem is that the solution entirely in xslt is too balky to be of use in creating and modifying stylesheets. What I really need is some kind of replacement mechanism, such as a macro or a define, to change <xsl:text>&#x0A;</xsl:text> into, say, &linefeed.

Much poking around led me to the ENTITY declaration. It was even suggested for this very whitespace problem! But whenever I try to add an <!ENTITY...> declaration by itself, the parser thinks it's a DTD and fails on the stylesheet; or if I put a <!DOCTYPE stylesheet...> around it, it fails when it hits the stylesheet because I haven't defined all elements used in the stylesheet. One promising example can be found at:

http://www.xml.com/p...14/trxml10.html

but this syntax failed because xsl:stylesheet was suddenly not defined.

Does anyone have an alternative mechanism for implementing this kind of macro in a stylesheet, or a way to make the ENTITY or DOCTYPE/ENTITY work? Help, help!

2 Replies

0
  dhosk's Photo
Posted Jan 26 2010 06:19 PM

HI, when you get stumped on something, the answer is sometimes the processor and sometimes the code. It would help if you specify the XSLT processor you are using (name and version), OS, and provide a sample of the XML and the desired result, as well as your XSL that doesn't get the results you want. You say "My problem is that I'm transforming from xml to xml, but need to add whitespace in one element. I've tried everything from preserve-space to enclosing whitespace in <xsl:text> tags, but somehow the Oracle XMLTransform() call, or something about the XMLElement() initialization, wipes whitespace out." I don't really understand your statement "the solution entirely in xslt is too balky to be of use in creating and modifying stylesheets," so I'm not sure that my comments will be suitable.

I presume you want a new line created by inserting a line break.
In XSLT, the usual solution has been <xsl:text>&amp;#10;<xsl:text> for a line break. Alternately, I have seen <xsl:text preserve-space="yes">
</xsl:text>
(a hard-coded line break within <xsl:text>) that will often will produce a line break in the output. Sometimes you need to create a variable to store the type of space you want to insert, then you can add it where you need it using a call-template.

And while you can use <xsl:strip-space="*"/> at the top of your XSL, you can also add <xsl:preserve-space="elementname"/> right after that to override the strip-space for your element <elementname>.

The XSLT websites provide lots of examples in articles like this one http://www.xmlplease.com/whitespace#s5, which looks pretty well written.
Note to people creating .txt from .xml: Whitespace output in text files is different than in XML output.(See also Dave Pawson http://www.dpawson.co.uk/xsl/ and Mulberry Technologies archive, http://www.biglist.c...-list/archives/ where people describe in detail what different problems they have had in adding white space or line breaks.) It sounds like you looked around some, but maybe more research or asking detailed questions on one of those sites will get you a more specific answer for your particular situation.
 : Jan 28 2010 02:55 PM
dhosk:

The XSLT processor is the Oracle XMLTransform() call, Oracle 9 and 10. I've tried oraxml and get different results, so it's only the database as far as I can tell. Which is why I wondered if some implicit initialization in XMLElement() might be removing the whitespace.

What I mean by "too balky" is that it's much easier for a user to enter \ than to enter <xsl:text>&amp;#10;<xsl:text>, especially since \ just forces the processor to treat the text node as non-whitespace, and tabs, endlines, and spaces can be added at will, while the xsl:text solution would require them to remember what hex 0A, 09, 20, etc mean.

Less troublesome for users would be something like &return, &tab, and the like.

I looked around a LOT - but I don't think I saw all of your links, I'll take a look, thanks!