不匹配的子元素也出现在XSL模板下

时间:2012-10-24 22:51:10

标签: xml xslt xslt-1.0

我有以下XML代码

<?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>

我只想获得所有具有type ='form'属性的节点的名称。所以我尝试了以下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>

但是我得SDSSJ JSFK HJDHH DJSJJ而不是SDSSJ JSFK HJDHH DJSJJ DONT Not。为什么不符合模板的子元素仍然出现?我该怎么做才能摆脱它们?

1 个答案:

答案 0 :(得分:6)

添加此模板:

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

示例:

<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>

默认情况下,文本会传递给输出。上面的模板将删除不匹配的文本。

这是关于默认XSLT模板规则的what the spec says

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.