b00kgrrl
b00kgrrl

Reputation: 597

How to display some text nodes in XSLT but not others

I need to display the text for a given node, while suppressing the text for the child node. I tried to handle this by creating an empty template for the child node, but it didn't work. How to suppress the text of a child node?

Here is the XML:

<?xml version="1.0" encoding="UTF-8"?>
<document>
    <item name="The Item">
        <richtext>
            <pardef/>
            <par def="20">
                <run>This text should </run>
                <run>be displayed.
                    <popup><popuptext>This text should not be displayed.</popuptext></popup>
                </run>
            </par>
        </richtext>
    </item>
</document>

Here is my stylesheet:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
   <xsl:output indent="yes" method="html"/>
   <xsl:template match="/*">
        <html>
            <body>
                <table border="1">
                        <xsl:apply-templates/>
                </table>
            </body>
        </html>
    </xsl:template>

    <xsl:template match="item">
        <tr>
            <td><xsl:value-of select="@name"/></td>
            <td>
                <xsl:apply-templates/>
            </td>
        </tr>
    </xsl:template>

    <xsl:template match="run">
         <xsl:value-of select="." separator=""/>
    </xsl:template>

    <xsl:template match="popuptext" />

</xsl:stylesheet>

Upvotes: 0

Views: 1399

Answers (2)

Matt Hogan-Jones
Matt Hogan-Jones

Reputation: 3103

If you only want to display the text for the run element, use select="text()":

<xsl:template match="run">
     <xsl:value-of select="text()" separator=""/>
</xsl:template>

If you use select="." it selects all of the content of the run element, which includes the content of its child elements.

I'm not sure this is 100% the best way to do it, but it does prevent the child element content of run from being displayed in your specific case.

My full version of the stylesheet is:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
   <xsl:output indent="yes" method="html"/>
   <xsl:template match="/*">
        <html>
            <body>
                <table border="1">
                        <xsl:apply-templates/>
                </table>
            </body>
        </html>
    </xsl:template>

    <xsl:template match="item">
        <tr>
            <td><xsl:value-of select="@name"/></td>
            <td>
                <xsl:apply-templates/>
            </td>
        </tr>
    </xsl:template>

    <xsl:template match="run">
         <xsl:value-of select="text()" separator=""/>
    </xsl:template>

    <xsl:template match="popuptext" />

</xsl:stylesheet>

Upvotes: 1

Daniel Haley
Daniel Haley

Reputation: 52858

You should be able to change your select="." to select="text()"...

<xsl:template match="run">
  <xsl:value-of select="text()"/>
</xsl:template>

Also, since you don't do an apply-templates from run, the template matching popuptext isn't needed.

Upvotes: 1

Related Questions