Subject: Re: Char node-type From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx> Date: Thu, 23 Nov 2000 11:21:20 +0000 |
Richard, > Since the translate function only deals with one-to-one character > mappings, we have written a template to process text() nodes which > processed the first character, then calls itself recursively to > process the rest of the string. This works fine so long as you don't > have more than about 600 characters in a single element - with a > long enough string you get stack overflows. The way that I usually do this is to define a set of replacements that I want to have made: <xsl:variable name="replacements-rtf"> <replace> <from><</from> <to><span class="entity">&lt;</span></to> </replace> <replace> <from>></from> <to><span class="entity">&gt;</span></to> </replace> ... </xsl:variable> <xsl:variable name="replacements" select="saxon:node-set($replacements-rtf)/replace" /> <!-- or select="msxsl:node-set($replacements-rtf)/replace" /> ...etc for other XSLT Processors' node-set extension functions... or select="document('')/*/xsl:variable[@name = 'replacements-rtf']/replace" /> --> then have a template that performs substitution based on this set of replacements: <xsl:template name="substitute"> <xsl:param name="string" /> <xsl:variable name="sub" select="$replacements[contains($string, from)][1]" /> <xsl:choose> <xsl:when test="$sub"> <xsl:variable name="before" select="substring-before($string, $sub/from)" /> <xsl:variable name="after" select="substring-after($string, $sub/from)" /> <xsl:if test="$before"> <xsl:call-template name="substitute"> <xsl:with-param name="string" select="$before" /> </xsl:call-template> </xsl:if> <xsl:copy-of select="$sub/to" /> <xsl:if test="$after"> <xsl:call-template name="substitute"> <xsl:with-param name="string" select="$after" /> </xsl:call-template> </xsl:if> </xsl:when> <xsl:otherwise><xsl:value-of select="$string" /></xsl:otherwise> </xsl:choose> </xsl:template> which is then called from a template that matches any text that is found: <xsl:template match="text()"> <xsl:call-template name="substitute"> <xsl:with-param name="string" select="." /> </xsl:call-template> </xsl:template> Now, this has disadvantages: each bit of the string gets examined multiple times - the more replacements you have the worse it gets - but if having to make a replacement is fairly rare, then the higher reliance of XPath functions might mean it's better for you? > It wouldn't be necessary to use this unpleasant and inefficient > technique if XPath defined in its data model, and XSLT supported, a > char node-type. (Isolating a single character would also allow us to > access its character value via the number function, which would be > handy for processing classes of Unicode characters.) XPointer has something like this with its string ranges. For example, in XPointer I could do: string-range(text(), '<') to get a number of string ranges representing all instances of the character '<' within the text()'s value. You could imagine a future version of XSLT incorporating XPointer and having a function to perform substitution on a set of string ranges. Sorry I can't be more help, Jeni --- Jeni Tennison http://www.jenitennison.com/ XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Char node-type, Richard Light | Thread | Re: Char node-type, Dave Hartnoll |
Re: A new XSL Formatter, MURAKAMI Shinyu | Date | Re: A new XSL Formatter, Nikolai Grigoriev |
Month |