tags:

views:

57

answers:

2

I have an XML document that has an XML node named "Description"

The Description node contains text like "This is a long description."

When the XML file is loaded and displays in a browser, I need just the word "long" to be italicized. I understand that I could use XSLT to style the entire Description node, but how do I use CSS styling on only a small part of the node content?

+1  A: 

You don't. As the CSS3 spec says,

Selectors define the following function:

expression ∗ element → boolean

I.e., there no concept of selecting anything other than an element.

If "long" is to be italicized, it will need to be placed in a separate inline element. <em> would likely be an appropriate choice.

You could do this on the server side, before the document is sent to the browser, or you could use JavaScript and possibly something as simple as a regexp match to do this on the client side.

ngroot
Thank you for your answer - how would I put an <em> tag within the content of my XML node with the < and > characters reserved? I really appreciate your help!
Aaron
@ngroot: Why you don't even mention an XSLT solution, despite the question is tagged so?
Alejandro
+2  A: 

This XSLT 1.0 stylesheet:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="text()[ancestor::Description]" name="replace">
        <xsl:param name="pString" select="."/>
        <xsl:choose>
            <xsl:when test="contains($pString,' long ')">
                <xsl:value-of select="substring-before($pString,' long ')"/>
                <i> long </i>
                <xsl:call-template name="replace">
                    <xsl:with-param name="pString" 
                    select="substring-after($pString,' long ')"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$pString"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

With this input:

<Description>This is a long description</Description>

Output:

<Description>This is a<i> long </i>description</Description>

And this XSLT 2.0 stylesheet:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="text()[ancestor::Description]">
        <xsl:analyze-string select="." regex="([\p{{P}}\p{{Z}}])long([\p{{P}}\p{{Z}}])">
            <xsl:matching-substring>
                <xsl:value-of select="regex-group(1)"/>
                <i>long</i>
                <xsl:value-of select="regex-group(2)"/>
            </xsl:matching-substring>
            <xsl:non-matching-substring>
                <xsl:value-of select="."/>
            </xsl:non-matching-substring>
        </xsl:analyze-string>
    </xsl:template>
</xsl:stylesheet>

Output:

<Description>This is a <i>long</i> description</Description>
Alejandro
Thank you - this did exactly what I needed!
Aaron
@Aaron: You're wellcome!
Alejandro