Pradep
Pradep

Reputation: 2024

Non Matching child elements also appear under XSL Templates

I have the following XML Code

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="new_proto.xsl"?>
<Return>
 <SDSSJ type="form" />
 <JSFK type="form" />
 <KJFK type="form2" />
 <HJDHH type="form"> New Val </HJDHH>
 <NNDJB type="some"> 
    <DJSJJ type="form">
       THIS
    </DJSJJ>
    <KAKKK type="nope">
    DONT
    </KAKKK>
 Not
</NNDJB>
</Return>

I just want to get the name of all the nodes which have the attribute type='form' . So i tried the following XSL.

  1 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  2    <xsl:output method="html" omit-xml-declaration="yes" indent="no"/>
  3       <xsl:template match="//*[@type='form']">
  4       <xsl:value-of select="name()" />
  5       </xsl:template>
  6 </xsl:stylesheet>

But instead of SDSSJ JSFK HJDHH DJSJJ , i get SDSSJ JSFK HJDHH DJSJJ DONT Not . Why are child elements which dont comply to the template appearing still ? What should i do to get rid of them ?

Upvotes: 3

Views: 1963

Answers (1)

Daniel Haley
Daniel Haley

Reputation: 52858

Add this template:

<xsl:template match="text()"/>

Example:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="html" omit-xml-declaration="yes" indent="no"/>

    <xsl:template match="//*[@type='form']">
        <xsl:value-of select="name()"/>
    </xsl:template>

    <xsl:template match="text()"/>

</xsl:stylesheet>

By default text is passed to the output. The above template will strip unmatched text.

Here's what the spec says about the default XSLT template rules:

There is a built-in template rule to allow recursive processing to continue in the absence of a successful pattern match by an explicit template rule in the stylesheet. This template rule applies to both element nodes and the root node. The following shows the equivalent of the built-in template rule:

<xsl:template match="*|/">
    <xsl:apply-templates/> 
</xsl:template>

There is also a built-in template rule for each mode, which allows recursive processing to continue in the same mode in the absence of a successful pattern match by an explicit template rule in the stylesheet. This template rule applies to both element nodes and the root node. The following shows the equivalent of the built-in template rule for mode m.

<xsl:template match="*|/" mode="m">
    <xsl:apply-templates mode="m"/> 
</xsl:template>

There is also a built-in template rule for text and attribute nodes that copies text through:

<xsl:template match="text()|@*">
    <xsl:value-of select="."/> 
</xsl:template>

The built-in template rule for processing instructions and comments is to do nothing.

<xsl:template match="processing-instruction()|comment()"/>

The built-in template rule for namespace nodes is also to do nothing. There is no pattern that can match a namespace node; so, the built-in template rule is the only template rule that is applied for namespace nodes.

The built-in template rules are treated as if they were imported implicitly before the stylesheet and so have lower import precedence than all other template rules. Thus, the author can override a built-in template rule by including an explicit template rule.

Upvotes: 7

Related Questions