[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message] Re: String parsing in XSLT/XPath?
Hi Ying, > I need to transform an XML doc to an HTML doc. There is one element > that contains multiple lines and will need to be shown in the HTML > doc as multiple lines as well. Bascially I will need to put <BR/> to > the end of each line of that element. You need to use a recursive template to search and replace within the string. Here is one: <xsl:template match="node()" mode="replaceLineBreaks" name="replaceLineBreaks"> <xsl:param name="string" select="." /> <xsl:choose> <!-- if the string contains a line break... --> <xsl:when test="contains($string, '
')"> <!-- give the part before the line break... --> <xsl:value-of select="substring-before($string, '
')" /> <!-- then a br element... --> <br /> <!-- and then call the template recursively on the rest of the string --> <xsl:call-template name="replaceLineBreaks"> <xsl:with-param name="string" select="substring-after($string, '
')" /> </xsl:call-template> </xsl:when> <!-- if the string doesn't contain a line break, just give its value, followed by a br element --> <xsl:otherwise> <xsl:value-of select="$string" /><br /> </xsl:otherwise> </xsl:choose> </xsl:template> You can apply this template to the ADDRESS element with: <xsl:apply-templates select="ADDRESS" mode="replaceLineBreaks" /> I doubt this is relevant, since you're dealing with addresses, which tend to be fairly short, but if you're dealing with long strings with lots of line breaks in them, then you may find it more efficient to use a divide-and-conquer approach whereby you split the remaining string. This has the advantage of limiting the depth of the recursion, and therefore the call stack, but the disadvantage of not being tail recursive and therefore not amenable to optimisation: <xsl:template match="node()" mode="replaceLineBreaks" name="replaceLineBreaks"> <xsl:param name="string" select="." /> <xsl:choose> <!-- if the string contains a line break... --> <xsl:when test="contains($string, '
')"> <!-- give the part before the line break... --> <xsl:value-of select="substring-before($string, '
')" /> <!-- then a br element... --> <br /> <!-- and then call the template recursively on the rest of the string, splitting it into two to limit the depth of the recursion --> <xsl:variable name="remainingString" select="substring-after($string, '
')" /> <xsl:variable name="halfRemainingStringLength" select="floor(string-length($remainingString) div 2)" /> <xsl:call-template name="replaceLineBreaks"> <xsl:with-param name="string" select="substring($remainingString, 1, $halfRemainingStringLength)" /> </xsl:call-template> <xsl:call-template name="replaceLineBreaks"> <xsl:with-param name="string" select="substring($remainingString, $halfRemainingStringLength + 1)" /> </xsl:call-template> </xsl:when> <!-- if the string doesn't contain a line break, just give its value --> <xsl:otherwise> <xsl:value-of select="$string" /> </xsl:otherwise> </xsl:choose> </xsl:template> With this, you will have to add the <br /> to the end of the string yourself. If performance is an issue, I suggest that you try both of the templates on your particular data and processor to see which is best for you; if neither is significantly faster than the other, then use the one you feel most comfortable with maintaining. I hope that helps, Jeni --- Jeni Tennison http://www.jenitennison.com/ XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
|
PURCHASE STYLUS STUDIO ONLINE TODAY!Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced! Download The World's Best XML IDE!Accelerate XML development with our award-winning XML IDE - Download a free trial today! Subscribe in XML format
|