Frage

I want to convert some plain text with special marker into HTML formatted text.

For example,

This is the original value

Th<italic>is is a <under>com<bold>bina</bold>tion</under></italic> text.

The original value as actual value (just for reference)

Th<italic>is is a <under>com<bold>bina</bold>tion</under></italic> text.

HTML format I expect as a result

Th<i>is is a <u>com<b>bina</b>tion</u></i> text.

I tried with below template but it can not be parsed by XSLT parser.

<xsl:template name="decorateValue">
<xsl:param name="originalString" />

<xsl:variable name="preString" select="substring-before($originalString, '&lt;')" />
<xsl:variable name="postString" select="substring-after($originalString, '&lt;')" />

<xsl:value-of select="$preString" />

<xsl:variable name="tagName" select="substring-before($postString, '&gt;')" />

<xsl:choose>
    <xsl:when test="$tagName='bold'">
            <xsl:element name="b">
    </xsl:when>
    <xsl:when test="$tagName='/bold'">
            </xsl:element>
    </xsl:when>
    <xsl:when test="$tagName='italic'">
            <xsl:element name="i">
    </xsl:when>
    <xsl:when test="$tagName='/italic'">
            </xsl:element>
    </xsl:when>
    <xsl:when test="$tagName='under'">
            <xsl:element name="u">
    </xsl:when>
    <xsl:when test="$tagName='/under'">
            </xsl:element>
    </xsl:when>
</xsl:choose>

<xsl:call-template name="decorateValue">
    <xsl:with-param name="originalString" 
                    select="substring-after($postString, '&gt;')" />
</xsl:call-template>
</xsl:template>

any idea to solve this?

I would appreciate in advance.

War es hilfreich?

Lösung

If you can actually keep the original text, your life would be easier. Then you can transform
Th<italic>is is a <under>com<bold>bina</bold>tion</under></italic> text. easily into xHTML

<xsl:template match="italic">
    <xsl:element name="i">
         <xsl:apply-templates />
    </xsl:element>
</xsl:template>

You can't mix your tags in your example. You open an xsl:when and open an xsl:element and then close the xsl:when. That is not valid XML!

So if you want to go with the encoded string you need something like:

<xsl:template name="decorateValue">
    <xsl:param name="originalString" />

    <xsl:if test="$originalString!=''">

        <xsl:variable name="preString" select="substring-before($originalString, '&lt;')" />
        <xsl:variable name="postString" select="substring-after($originalString, '&lt;')" />
        <xsl:variable name="endString" select="'magic happens here!'" />

        <xsl:value-of select="$preString" />

        <xsl:variable name="tagName" select="substring-before($postString, '&gt;')" />
        <xsl:variable name="restString" select="'magic happens here!'" />

        <xsl:choose>
            <xsl:when test="$tagName='bold'">
                <xsl:element name="b">
                    <xsl:call-template name="decorateValue">
                        <xsl:with-param name="originalString" 
                            select="$restString" />
                    </xsl:call-template>
                </xsl:element>
            </xsl:when>
            <xsl:when test="$tagName='italic'">
                <xsl:element name="i">
                    <xsl:call-template name="decorateValue">
                        <xsl:with-param name="originalString" 
                            select="$restString" />
                    </xsl:call-template>
                </xsl:element>
            </xsl:when>
            <xsl:when test="$tagName='under'">
                <xsl:element name="u">
                    <xsl:call-template name="decorateValue">
                        <xsl:with-param name="originalString" 
                            select="$restString" />
                    </xsl:call-template>
                </xsl:element>
            </xsl:when>
        </xsl:choose>
        <xsl:value-of select="$endString" />
    </xsl:if>
</xsl:template>

You see 2 places where 'magic happens here'. This is where you need to apply the string-before-last and string-after-last patterns (which are a PITA in XSLT). The best explanation can be found in the XSLT Cookbook (and you want to have XSLT 2.0 at least.

Hope the pointers help. You might consider breaking the pattern into individual, so you don't fish for > alone, but the full tags. You still need to use the before-last / after-last functions.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top