Reputation: 1233
I am trying to remove commas from my xml file using xslt. How can I correctly replace any commas included in node or attribute values with a space?
Here is my xslt file:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:wd="urn:com.workday/bsvc">
<xsl:output method="text" encoding="utf-8" media-type="text/plain" />
<xsl:strip-space elements="*"/>
<xsl:variable name="newline" select="'
'" />
<xsl:variable name="tab" select="'	'" />
<xsl:variable name="comma" select="','" />
<xsl:variable name="padding" select="' '" /> <!-- 30 spaces for padding -->
<!-- Longest Column Header Text is 39 letters long -->
<xsl:variable name="FAO" select="concat('FAO', $padding, $padding)" />
<xsl:variable name="FAO1" select="concat('FAO REFERENCE ID', '')" />
<xsl:variable name="FAO2" select="concat('FAO TYPE', $padding)" />
<xsl:variable name="RESP" select="concat('RESPONSIBLE PERSON', $padding, $padding, $padding, $padding)" />
<xsl:template match="/">
<!-- <xsl:variable name="textVal" select="*/text()" />
<xsl:value-of select="translate($textVal, ',' ,' ')" />-->
<xsl:value-of select="$FAO"/><xsl:value-of select="$comma"/>
<xsl:value-of select="$FAO1"/><xsl:value-of select="$comma"/>
<xsl:value-of select="$FAO2"/><xsl:value-of select="$comma"/>
<xsl:value-of select="$RESP"/><xsl:value-of select="$comma"/>
<xsl:value-of select="$newline"/>
<xsl:for-each select="/wd:Report_Data/wd:Report_Entry">
<xsl:value-of select="substring(concat(wd:FAO, $padding, $padding, $padding, $padding, $padding), 1, string-length($FAO))" /><xsl:value-of select="$comma"/>
<xsl:value-of select="substring(concat(wd:FAO_REFERENCE_ID, $padding, $padding, $padding, $padding, $padding), 1, string-length($FAO1))" /><xsl:value-of select="$comma"/>
<xsl:value-of select="substring(concat(wd:FAO_TYPE, $padding, $padding, $padding, $padding, $padding), 1, string-length($FAO2))" /><xsl:value-of select="$comma"/>
<xsl:value-of select="substring(concat(wd:RESPONSIBLE_PERSON/@wd:Descriptor, $padding, $padding, $padding, $padding, $padding), 1, string-length($RESP))" /><xsl:value-of select="$comma"/>
</xsl:for-each>
</xsl:template>
<xsl:template match="*">
<xsl:variable name="textVal" select="*/text()" />
<xsl:value-of select="translate($textVal, ',' ,' ')" />
</xsl:template>
</xsl:stylesheet>
My output is a CSV file so I want to replace any nodes and attribute values that contain commas with spaces.
The second template that tries to replace commas with a space does not work. I also tried placing those 2 statements at the start of the first template but that did not work as well.
Upvotes: 0
Views: 7911
Reputation: 52888
If you're using XSLT 2.0, you could use xsl:character-map.
Example...
XML Input
<test>Bacon ipsum dolor sit amet sirloin, venison, swine,
ground round, pastrami, rump pig, kevin turducken.</test>
XSLT 2.0
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" use-character-maps="map"/>
<xsl:character-map name="map">
<xsl:output-character character="," string=" "/>
</xsl:character-map>
</xsl:stylesheet>
Text Output
Bacon ipsum dolor sit amet sirloin venison swine
ground round pastrami rump pig kevin turducken.
Upvotes: 1
Reputation: 122414
The translate()
in your *
template does nothing because that template is never used - your template match="/"
just does a series of value-of
instructions, it never calls apply-templates
to cause the *
template to fire.
You need to put the translate in each value-of
individually, e.g.
<xsl:value-of select="translate(substring(concat(wd:FAO,$padding, $padding,
$padding, $padding, $padding), 1, string-length($FAO)), ',', ' ')" />
If this were XSLT 2.0 you could define a custom function to make this a bit shorter, but in XSLT 1.0 you'd have to use apply-templates
and with-param
which probably works out at least as verbose as the alternative.
<xsl:for-each select="/wd:Report_Data/wd:Report_Entry">
<xsl:apply-templates select="wd:FAO">
<xsl:with-param name="header" select="$FAO"/>
</xsl:apply-templates>
<xsl:value-of select="$comma"/>
<xsl:apply-templates select="wd:FAO_REFERENCE_ID">
<xsl:with-param name="header" select="$FAO1"/>
</xsl:apply-templates>
<xsl:value-of select="$comma"/>
<xsl:apply-templates select="wd:FAO_TYPE">
<xsl:with-param name="header" select="$FAO2"/>
</xsl:apply-templates>
<xsl:value-of select="$comma"/>
<!-- etc -->
</xsl:for-each>
with the following template
<xsl:template match="wd:*">
<xsl:param name="header" />
<xsl:value-of select="translate(substring(concat(., $padding, $padding,
$padding, $padding, $padding), 1, string-length($header)), ',', ' ')" />
</xsl:template>
Upvotes: 1
Reputation: 3742
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:wd="urn:com.workday/bsvc">
<xsl:output method="text" encoding="utf-8" media-type="text/plain" />
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:for-each select="@*|text()">
<xsl:variable name="textVal" select="current()" />
<xsl:value-of select="translate($textVal, ',' ,' ')" />
</xsl:for-each>
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
Upvotes: 1