您好我已经执行了一个转换,如果它为空,则会删除标记。
我想检查我的转换是否正常工作,因此我不再手动检查它,而是编写了一个XSLT代码,它只是检查OUTPUT XML中是否存在该特定标记,如果它是null,那么第二个XSLT应输出文本“FOUND”。 (我实际上并不需要一些XML类型的输出,但我只是使用XSLT进行搜索。)
当我尝试使用这个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文件中存在的所有TEXT DATA
为了避免这种情况,我不得不编写这段代码::
<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忽略所有其他文本?是所有XML解析器的行为或仅我自己的行为(我使用的是msxml解析器)。
答案 0 :(得分:145)
为什么前一个代码输出TEXT, 为什么我要坚持XSL忽略所有 其他文字?是的行为 所有XML解析器或仅我自己的
您正在发现规范中指定的最基本的XSLT功能之一:built-in templates of XSLT 。
来自the Spec :
有一个内置的模板规则 允许递归处理继续 在没有成功模式的情况下 匹配显式模板规则 样式表。此模板规则 适用于两个元素节点和 根节点。以下显示了 相当于内置模板 规则:
<xsl:template match="*|/"> <xsl:apply-templates/> </xsl:template>
还有一个内置模板规则 对于每种模式,它允许递归 处理继续在同一个 模式在没有成功的情况下 模式匹配显式模板 样式表中的规则。这个模板 规则适用于两个元素节点和 根节点。以下显示了 相当于内置模板 模式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()"/>
内置模板规则 命名空间节点也无所作为。 没有可以匹配的模式 名称空间节点所以,内置 模板规则是唯一的模板 应用于命名空间的规则 节点
内置模板规则是 如同进口一样对待 隐式地在样式表之前和 因此导入优先级低于 所有其他模板规则。就这样 作者可以覆盖内置的 模板规则通过包含显式 模板规则。
因此,报告的行为是应用内置模板的结果 - 这三个模板中的第一个和第二个。
使用您自己的模板覆盖内置模板是一个很好的XSLT设计模式,每当调用时都会发出错误消息,以便程序员立即知道他的转换是“泄漏”:
例如,如果有这个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
Michael Kay稍后为XSLT 3.0添加
在XSLT 3.0中,您可以在xsl:mode
声明中指定回退行为,而不是添加全部捕获模板规则。例如,<xsl:mode on-no-match="shallow-skip"/>
会导致所有未匹配的节点(包括文本节点)被跳过,而<xsl:mode on-no-match="fail"/>
会将不匹配视为错误,<xsl:mode warning-on-no-match="true"/>
会导致警告。
答案 1 :(得分:14)
XSL中有几个built in template rules,其中一个就是:
<xsl:template match="text()|@*">
<xsl:value-of select="."/>
</xsl:template>
输出文字。