Reputation: 11458
I have the following XML generated:
<InvoiceStreet>Rod House Rods Way Euro Industrial Estate</InvoiceStreet>
This contains white-space, I'd like to use xslt to transform it to the following:
<AddressLine>Rod House Rods Way</AddressLine>
<AddressLine>Euro Industrial Estate</AddressLine>
At the moment I'm only able to output it like so:
<AddressLine>Rod House Rods Way
Euro Industrial Estate</AddressLine>
Is there a way to do this using XSLT?
Here is what I currently have:
<Address>
<AddressLine>
<xsl:value-of select="/*/*/*/*/*/xsales:DeliveryStreet" />
</AddressLine>
</Address>
Upvotes: 0
Views: 70
Reputation: 66781
From the output that you posted, it appears that the input has the components of the <xsales:DeliveryAddress>
address separated by a line-feed character.
If so, you can split xsales:DeliveryAddress
on line feeds and put each line in it's own <AddressLine>
using a recursive template that looks for a line-feed character, creates a new <AddressLine>
for content before the line-feed and then processes the text after it with a subsequent call to the template:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsales="xsales"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:mailplus="http://api.mailplus.nl/rss/mailplus/">
<xsl:output method="html" indent="yes"/>
<xsl:param name="ItemsToShow" select="2"/>
<xsl:param name="ShowItemDetails"/>
<xsl:param name="ShowItemDate"/>
<xsl:param name="Locale"/>
<xsl:param name="Target"/>
<xsl:template match="rss">
<Address>
<xsl:call-template name="AddressLines">
<xsl:with-param name="txt"
select="/*/*/*/*/*/xsales:DeliveryStreet"/>
</xsl:call-template>
</Address>
</xsl:template>
<xsl:template name="AddressLines">
<xsl:param name="txt"/>
<!--default value for delimiter to use line-feed character -->
<xsl:param name="delimiter" select="'
'"/>
<xsl:choose>
<xsl:when test="contains($txt, $delimiter)">
<AddressLine>
<xsl:value-of select="normalize-space(
substring-before($txt,
$delimiter))"/>
</AddressLine>
<xsl:call-template name="AddressLines">
<xsl:with-param name="txt"
select="substring-after($txt,
$delimiter)"/>
<xsl:with-param name="delimiter" select="$delimiter"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<!--filter out whitespace-only lines(from trailing line feeds)-->
<xsl:if test="normalize-space($txt)">
<AddressLine>
<xsl:value-of select="$txt"/>
</AddressLine>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
Upvotes: 1
Reputation: 16718
Use substring Function, try using this piece of code snippet instead:
<Address>
<AddressLine>
<xsl:value-of select="substring(/*/*/*/*/*/xsales:DeliveryStreet,0,18)" />
</AddressLine>
<AddressLine>
<xsl:value-of select="substring(/*/*/*/*/*/xsales:DeliveryStreet,19,22)" />
</AddressLine>
</Address>
Better Approach
Get the length of the complete address. e.g. the length is 41 for the above provided sample string.
<xsl:variable name="addressLength" select="string-length(/*/*/*/*/*/xsales:DeliveryStreet)" />
Divide the length by 2 and truncate the floating part, i.e. you will get 20
<xsl:variable name="splitLength" select="$addressLength / 2" />
Now apply the substring function from zero (0) to splitLength
variable
substring(/*/*/*/*/*/xsales:DeliveryStreet, 0, $splitLength)
e.g. you will get the output as "Rod House Rods Way E"
Again apply the substring function upto last occurance of space using LastIndexOf
template.
e.g. you will get the desired output as "Rod House Rods Way"
For LastIndexOf
template approach, you can refer to this post, XSLT: Finding last occurance in a string
Hope this will solve your problem for dynamic addresses, Cheers!
Upvotes: 1