I have a space-separated list of coordinate tuples, with arbitrarily many tuples. Each tuple consists of a space-separated list of 2-dimensional coordinates. E.g. "1.1 2.8 1.2 2.9" represents a line from POINT(1.1 2.8) to POINT(1.2 2.9). I need this to instead be "1.1,2.8 1.2,2.9". How would I use XSLT to perform the replacement of space-to-comma between pairs of numbers? I have the "string(gml:LinearRing/gml:posList)".
This is being used on a Java Web Service that spits out GML 3.1.1 features with geometries. The service supports optional KML output, by using XSLT to transform the GML document into a KML document (at least, the chunks deemed "important"). I am locked into XSLT 1.0, so regex from XSLT 2.0 is not an option.
I am aware that GML uses lat/lon while KML uses lon/lat. That's being handled before XSLT, though it would be nice to have that also done with XSLT.
Thank you for your solution, Dimitre. I modified it a little to fit my needs, so I'll include that here in case it helps anyone else. It performs recursion through the coordinate list, assuming 2-dimensional tuples.
This performs two functions: axis swapping (lat/lon for lon/lat, per GML and KML specs) and changing the coordinate separator within each tuple from space ' ' to comma ','.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:gml="http://www.opengis.net/gml" exclude-result-prefixes="gml">
<xsl:output method="xml" encoding="UTF-8" indent="yes" />
<!-- other portions omitted -->
<xsl:template match="gml:pos">
<xsl:call-template name="coordinateSequence">
<xsl:with-param name="coords" select="normalize-space(string(.))" />
</xsl:call-template>
</xsl:template>
<xsl:template match="gml:posList">
<xsl:call-template name="coordinateSequence">
<xsl:with-param name="coords" select="normalize-space(string(.))" />
</xsl:call-template>
</xsl:template>
<xsl:template name="coordinateSequence">
<xsl:param name="coords" />
<xsl:if test="string-length($coords) > 0">
<xsl:variable name="lat" select="substring-before($coords, ' ')" />
<xsl:variable name="lon">
<xsl:value-of select="substring-before(substring-after($coords, ' '), ' ')" />
<xsl:if test="string-length(substring-before(substring-after($coords, ' '), ' ')) = 0">
<xsl:value-of select="substring-after($coords, ' ')" />
</xsl:if>
</xsl:variable>
<xsl:variable name="remainder" select="substring-after(substring-after($coords, ' '), ' ')" />
<xsl:value-of select="concat($lon, ',', $lat)" />
<xsl:if test="string-length($remainder) > 0">
<xsl:value-of select="' '" />
<xsl:call-template name="coordinateSequence">
<xsl:with-param name="coords" select="$remainder" />
</xsl:call-template>
</xsl:if>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
This transformation (also shows the intermediary steps):
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/*">
<xsl:variable name="vNorm" select="normalize-space()"/>
<xsl:variable name="vP1" select=
"concat(substring-before(., ' '), ',',
substring-before(substring-after($vNorm, ' '),' ')
)"/>
<xsl:variable name="vPart2" select="substring-after(substring-after($vNorm,' '),' ')"/>
<xsl:variable name="vP2" select=
"concat(substring-before($vPart2, ' '), ',',
substring-after($vPart2, ' ')
)"/>
<xsl:value-of select="$vP1"/>
==========
<xsl:value-of select="$vP2"/>
==========
<xsl:value-of select="concat($vP1, ' ', $vP2)"/>
</xsl:template>
</xsl:stylesheet>
when applied on this XML document:
<t>1.1 2.8 1.2 2.9</t>
produces the wanted, correct result (the last line):
1.1,2.8
==========
1.2,2.9
==========
1.1,2.8 1.2,2.9
For convenience, this code can be placed in to a named template to be called for each wanted Line:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/*">
<xsl:call-template name="convertLine"/>
</xsl:template>
<xsl:template name="convertLine">
<xsl:param name="pStr" select="."/>
<xsl:variable name="vNorm" select="normalize-space($pStr)"/>
<xsl:variable name="vP1" select=
"concat(substring-before($pStr, ' '), ',',
substring-before(substring-after($vNorm, ' '),' ')
)"/>
<xsl:variable name="vPart2" select="substring-after(substring-after($vNorm,' '),' ')"/>
<xsl:variable name="vP2" select=
"concat(substring-before($vPart2, ' '), ',',
substring-after($vPart2, ' ')
)"/>
<xsl:value-of select="concat($vP1, ' ', $vP2)"/>
</xsl:template>
</xsl:stylesheet>