itsbalur
itsbalur

Reputation: 1002

XSLT Format string with "less than" symbol

I have an XML node, which is part of a larger XML as below, which contains certain symbols in subscript.

<MT N="Abstract" V="Centre-of-mass energies in the region 142&lt;W&lt;sub&gt;γp&lt;/sub&gt;&lt;293 GeV with the ZEUS detector at HERA using an integrated luminosity"/>

I need to format the value in @V attribute, such that every &lt; which is succeeded by an alphabet as in &lt;W above, should be replaced as &lt; W, with a single space between them, when parsed with an XSLT.

Is this possible? XSLT 1.0 solution preferred.

Upvotes: 1

Views: 3333

Answers (2)

Woody
Woody

Reputation: 5130

It is possible. In XSLT 2.0 it would be a doddle (with a regular expression). However, this is direct 'what you said' script in XSLT 1.0:

<xsl:template match="/">
    <xsl:call-template name="process">
        <xsl:with-param name="text" select="/tutorial/MT/@V"/>
    </xsl:call-template>
</xsl:template>

<xsl:template name="process">
    <xsl:param name="text" select="."/>
    <xsl:variable name="modtext" select="translate($text,'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')"/>
    <xsl:variable name="pretext" select="substring-before($modtext,'&lt;a')"/>        
    <xsl:choose>
        <xsl:when test="not($pretext)">
            <xsl:value-of select="$text"/>
        </xsl:when>
        <xsl:otherwise>
            <xsl:variable name="endpos" select="string-length($pretext)+1"/>
            <xsl:value-of select="concat(substring($text,1, $endpos),' ')"/>
            <xsl:call-template name="process">
                <xsl:with-param name="text"
                    select="substring($text,$endpos+1)"/>
            </xsl:call-template>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

which produces what you asked for, although it acts funny with numbers and / characters.

It produces:

Centre-of-mass energies in the region 142&lt; W&lt; sub&gt;γp&lt;/sub&gt;&lt;293 GeV with the ZEUS detector at HERA using an integrated luminosity

Obviously if you update the translate with / and 1234567890 it will handle numbers and slashes too.

Upvotes: 2

Michael Kay
Michael Kay

Reputation: 163352

Easy in XSLT 2.0:

replace(@V, '(&lt;)(\p{L})', '$1 $2')

Much harder in XSLT 1.0, sufficiently hard that I don't have time to attempt it.

Upvotes: 0

Related Questions