Hi Folks,
I want to convert this:
<Airport_Name>LOWELL FLD </Airport_Name>
to this:
<name>LOWELL FLD</name>
The value of the <name> element must be identical to the value of the
<Airport_Name> element, except without the trailing spaces.
Multiple internal consecutive spaces, if present, must be preserved. Hence,
the normalize-space() function cannot be used.
I have a solution, but it requires a mix of XPath and a user-defined XSLT
function. I seek a pure XPath solution.
Here is the approach I took:
Convert the value of Airport_Name to a sequence of codepoints:
let $cp := string-to-codepoints(string(Airport_Name)) return
Reverse the sequence of codepoints:
let $rev := reverse($cp) return
Get the index of the first non-blank character:
let $idx := f:index-of-first-non-blank-char($rev,1) return
Extract the subsequence starting at the index:
let $subseq := $rev[position() ge $idx] return
Reverse the subsequence:
let $rev2 := reverse($subseq) return
Convert the codepoints to a string and return the string:
codepoints-to-string($rev2)
Obviously, f:index-of-first-non-blank-char() is not XPath; it's a user-defined
XSLT function that I created:
<xsl:function name="f:index-of-first-non-blank-char" as="xs:integer">
<xsl:param name="str" as="xs:integer+"/>
<xsl:param name="idx" as="xs:integer"/>
<xsl:choose>
<xsl:when test="$str[1] ne 32"> <!-- 32 = decimal value of space char
-->
<xsl:sequence select="$idx"/>
</xsl:when>
<xsl:otherwise>
<xsl:sequence
select="f:index-of-first-non-blank-char($str[position() gt 1], $idx + 1)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:function>
There must be a better (simpler, shorter, more straightforward) way to solve
this problem.
Help, please!
/Roger
|