为什么XSLT默认输出所有文本?
嗨,我已经执行了一个转换,如果它是空的,则会丢弃一个标记。
我想检查我的转换是否正常工作,所以不是手动检查,而是编写了一个XSLT代码,它只是检查OUTPUT XML中特定标记的存在,如果它是null,那么第二个XSLT应该输出一个文字“find”。 (我实际上并不需要一些XMLtypes的输出,但我只是使用XSLT进行search。)
当我尝试使用这个XSL代码::
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/SiebelMessage//SuppressCalendar[.!='']"> FOUND </xsl:template> </xsl:stylesheet>
它输出XML文件中的所有文本数据,
为了避免这一点,我不得不写这个代码::
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/SiebelMessage//SuppressCalendar[.!='']"> FOUND </xsl:template> <xsl:template match="text()"/> </xsl:stylesheet>
为什么前面的代码输出TEXT,为什么我要坚持XSL忽略所有其他文本? 是所有XMLparsing器的行为还是我自己的行为(我正在使用msxmlparsing器)。
为什么前面的代码输出TEXT,为什么我要坚持XSL忽略所有其他文本? 是所有XMLparsing器的行为还是我自己的行为
您正在发现规范中指定的最基本的XSLT特性之一:XSLT的内置模板 。
从规格 :
有一个内置的模板规则,允许recursion处理在没有成功的模式匹配的情况下通过样式表中的显式模板规则继续。 此模板规则适用于元素节点和根节点。 以下显示了内置模板规则的等效内容:
<xsl:template match="*|/"> <xsl:apply-templates/> </xsl:template>
对于每种模式,还有一个内置的模板规则,在样式表中显式的模板规则不存在成功的模式匹配的情况下,允许recursion处理在相同的模式下继续。 此模板规则适用于元素节点和根节点。 以下显示了模式m的内置模板规则的等效项。
<xsl:template match="*|/" mode="m"> <xsl:apply-templates mode="m"/> </xsl:template>
还有一个用于文本和属性节点的内置模板规则,可以通过以下方式复制文本:
<xsl:template match="text()|@*"> <xsl:value-of select="."/> </xsl:template>
处理指令和注释的内置模板规则是什么都不做。
<xsl:template match="processing-instruction()|comment()"/>
命名空间节点的内置模板规则也是什么也不做。 没有可以匹配命名空间节点的模式; 因此,内置模板规则是应用于命名空间节点的唯一模板规则。
内置的模板规则被视为在样式表之前隐式导入,因此具有比所有其他模板规则更低的导入优先级。 因此,作者可以通过包含明确的模板规则来覆盖内置的模板规则。
所以,报告的行为是应用内置模板的结果 – 它们三个中的第一个和第二个。
这是一个很好的XSLTdevise模式,可以用自己的模板覆盖内置模板 ,每次调用时都会发出错误消息,以便程序员立即知道他的转换是“泄漏”的:
例如 ,如果有这个XML文档:
<a> <b> <c>Don't want to see this</c> </b> </a>
并用这个转换进行处理 :
<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="a|b"> <xsl:copy> <xsl:attribute name="name"> <xsl:value-of select="name()"/> </xsl:attribute> <xsl:apply-templates/> </xsl:copy> </xsl:template> </xsl:stylesheet>
结果是 :
<a name="a"> <b name="b">Don't want to see this</b> </a>
而程序员将会大大地困惑不知所措的文字是如何出现的。
但是,只要添加这个catch-all template
,就可以避免这种混淆,立即发现错误 :
<xsl:template match="*"> <xsl:message terminate="no"> WARNING: Unmatched element: <xsl:value-of select="name()"/> </xsl:message> <xsl:apply-templates/> </xsl:template>
现在,除了令人困惑的输出之外,程序员会立即得到一个警告来解释这个问题 :
WARNING: Unmatched element: c
在XSL中有几个内置的模板规则 ,其中之一是这样的:
<xsl:template match="text()|@*"> <xsl:value-of select="."/> </xsl:template>
它输出文字。