这是一个简单的案例。
这是我的XML:
<?xml version="1.0" encoding="utf-8" ?>
<dogs>
<dog type="Labrador">
<Name>Doggy</Name>
</dog>
<dog type="Batard">
<Name>Unknown</Name>
</dog>
</dogs>
此XML与两个Xslt一起使用。这是常见的:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="text"/>
<xsl:template match="dogs">
<xsl:text>First template </xsl:text>
<xsl:apply-templates select="." mode="othertemplate" />
</xsl:template>
</xsl:stylesheet>
这是孩子:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:include href="transform.xslt"/>
<xsl:template match="dogs" mode="othertemplate">
<xsl:text>		Other template</xsl:text>
</xsl:template>
</xsl:stylesheet>
孩子包括普通孩子(称为transform.xslt)。
当我执行孩子时,我得到了预期的结果:
First template
Other template
当我执行常用的时,我得到了这个奇怪的结果:
First template
Doggy
Unknown
常见的模板应用模式“othertemplate”。此模式仅在子xslt中包含。
我想要的是,如果没有模板“othertemplate”,那么就不应输出任何内容。
我不想为所有不必使用此模板模式的xslt文件包含模式为“othertemplate”的模板和空体...
我该怎么办?
由于
答案 0 :(得分:10)
由于XSLT的内置模板规则(也称为默认模板),因此会显示元素内容和额外的空白。当没有其他匹配模板时,将应用这些规则。
是内置模板规则<xsl:template match="*|/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="text()|@*">
<xsl:value-of select="."/>
</xsl:template>
<xsl:template match="processing-instruction()|comment()"/>
内置模板规则递归处理根节点和元素节点并复制文本(如果选择了属性节点,则复制文本属性值)。用于处理指令和注释的内置模板规则是什么都不做。默认情况下不处理命名空间节点。请注意,<xsl:apply-templates/>
实际上是<xsl:apply-templates select="child::node()"/>
的简写,因此它不会选择属性或命名空间节点。
每种模式还有一个内置模板规则。这些模板类似于元素和root的默认模板,除非它们以相同的模式继续处理。
<xsl:template match="*|/" mode="foobar">
<xsl:apply-templates mode="foobar"/>
</xsl:template>
由于您的样式表没有与模式dogs
匹配的othertemplate
模板,因此会应用此内置模板规则,在这种情况下会导致处理所有子节点并最终打印文本节点。源文档元素之间的缩进和换行也是文本节点,因此它们也会被打印并在输出中产生额外的空白。
<xsl:apply-templates select="."/>
通常apply-templates
用于处理后代。在您的示例代码中,您在调用apply-templates
时选择了当前节点。如果由于其中有apply-templates
命令而应用模板本身,则可能导致非终止循环。以下示例
<xsl:template match="foobar">
<!-- This is an infinite loop -->
<xsl:apply-templates select="."/>
</xsl:template>
顺便说一下。关于组合样式表的一般规则,请仔细考虑应运行哪个模板以及应导入或包含哪个模板。 (我有read作为一般惯例,Michael Kay似乎建议使用<xsl:import>
将一般情况样式表导入特殊情况样式表,而不是反过来。)
答案 1 :(得分:6)
The built-in XSLT templates 。因此,选择了文本节点的内置模板,并且(根据定义)它输出文本节点。
要取消此操作,您需要使用空模板覆盖所需模式中的文本节点的内置模板(也可能用于元素):
<xsl:template match="text()" mode="othertemplate"/>
在导入的样式表中包含上述内容。