John Cornellier
John Cornellier

Reputation: 105

XSLT select text without children

XML:

<data><ph>Foo</ph>Bar</data>

XSL:

<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
    <xsl:apply-templates select="data/ph"/>
    <xsl:apply-templates select="data"/>
</xsl:template>
<xsl:template match="data/ph">
    <xsl:value-of select="."/>
 </xsl:template>
<xsl:template match="data">
    <xsl:value-of select="."/>
</xsl:template>

When the XSL selects the text in the /data/ with <xsl:template match="data"><xsl:value-of select="."/> it is also selecting the text in the child entity data/ph. How do I point to only the text of /data/, without including the text of /data/ph/ ?

My output should be: FooBar, and not FooFooBar.

Upvotes: 3

Views: 1215

Answers (1)

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243469

When the XSL selects the text in the /data/ with <xsl:template match="data"><xsl:value-of select="."/> it is also selecting the text in the child entity data/ph. How do I point to only the text of /data/, without including the text of /data/ph/ ?

Use:

<xsl:copy-of select="text()"/>

This copies all text node-children of the current node.

With this correction, the whole transformation becomes:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

    <xsl:template match="/">
        <xsl:apply-templates select="data/ph"/>
        <xsl:apply-templates select="data"/>
    </xsl:template>

    <xsl:template match="data/ph">
        <xsl:value-of select="."/>
     </xsl:template>

    <xsl:template match="data">
        <xsl:copy-of select="text()"/>
    </xsl:template>
</xsl:stylesheet>

and when applied on the provided XML document:

<data><ph>Foo</ph>Bar</data>

the wanted, correct result is produced:

FooBar

Upvotes: 2

Related Questions