【发布时间】:2011-05-28 01:50:40
【问题描述】:
在
<xsl:template name="temp_name" mode="mode">
mode是什么意思?我搜索了很多资源,但找不到示例。那么有人可以举个例子来解释一下吗?
【问题讨论】:
在
<xsl:template name="temp_name" mode="mode">
mode是什么意思?我搜索了很多资源,但找不到示例。那么有人可以举个例子来解释一下吗?
【问题讨论】:
给模板命名和模式并没有太大意义。
name属性完全标识一个模板,不能有两个同名不同模式的模板。
mode 属性允许使用不同的模式多次处理相同的节点。
这是一个简短的例子:
<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="num[position() mod 3 = 1]">
<tr>
<xsl:apply-templates mode="copy" select=
". | following-sibling::*[not(position() >2)]"/>
</tr>
</xsl:template>
<xsl:template match="*" mode="copy">
<td><xsl:value-of select="."/></td>
</xsl:template>
<xsl:template match="num"/>
</xsl:stylesheet>
当此转换应用于以下 XML 文档时:
<nums>
<num>01</num>
<num>02</num>
<num>03</num>
<num>04</num>
<num>05</num>
<num>06</num>
<num>07</num>
<num>08</num>
<num>09</num>
<num>10</num>
</nums>
结果是数字显示在三个tr(行)中,每行包含三列(最后一行可能除外):
<tr>
<td>01</td>
<td>02</td>
<td>03</td>
</tr>
<tr>
<td>04</td>
<td>05</td>
<td>06</td>
</tr>
<tr>
<td>07</td>
<td>08</td>
<td>09</td>
</tr>
<tr>
<td>10</td>
</tr>
在此转换中,任何位置无法以3*k +1 形式表示的num 元素(其中k 是一个整数)都与具有空主体的模板匹配,因此不会被处理。
但是,我们想要处理所有应该构成一行单元格的num 元素。为此,我们使用 xslt 指令处理它们:
<xsl:apply-templates mode="copy" select=
". | following-sibling::*[not(position() >2)]"/>
这意味着:“不要应用到通常会应用的选定节点模板(在无模式下),但应用处于copy 模式下的模板”
因此,我们不会忽略选定的num 元素,而是在copy 模式下处理它们,并创建一行td。
模板规则:
<xsl:template match="num"/>
必须覆盖 xslt 内置模板(默认处理),否则会导致位置无法表示为 3*k +1 的 num 节点的字符串值被输出。
因此,这些节点由两个模板处理:
<xsl:template match="num"/>
和
<xsl:apply-templates mode="copy" select=
". | following-sibling::*[not(position() >2)]"/>
因此我们得到了想要的结果。
通过一个好的 XSLT 调试器逐步了解这些模板是如何应用的会很有启发意义。
【讨论】:
mode 就像一个过滤器,用于确定哪些模板可用于处理节点,而不是特定模板的替代方案之一,可以从它的名称中推测出来,如果 mode 能够被动态定义,哪种类型的使用会受益。
mode 的误解。
<xsl:apply-templates select="phone" />
<xsl:apply-templates select="phone" mode="accountNumber"/>
<xsl:template match="phone">
<TD>A</TD>
</xsl:template>
<xsl:template match="phone" mode="accountNumber">
<TD>B</TD>
</xsl:template>
在这里链接一个简单的例子:https://msdn.microsoft.com/en-us/library/ms256045%28v=vs.110%29.aspx
【讨论】:
mode,所以这里不应该不解释就提供它。
mode 属性允许以多种方式处理相同的 XML 元素。
如果要使用mode 属性,模板必须具有match 属性,因此它们不适用于仅依赖name 属性进行调用的模板。
它们应用到xsl:apply-templates 以确定哪个xsl:templates 将响应,因此使用模式的应用只会调用使用相同模式的模板。没有模式的模板只会响应没有模式的应用。
例如,您可能希望将 XML paragraph 元素呈现为 HTML p 元素以供查看,但将其呈现为 form 以供编辑。
然后可以通过以下方式呈现以供查看:
<xsl:template match="paragraph">
<p>...</p>
</xsl:template>
通过调用时匹配 XML 文档中的 paragraph 标记:
<xsl:apply-templates />
反之,渲染以供编辑使用:
<xsl:template match="paragraph" mode="edit">
<form>...</form>
</xsl:template>
通过调用:
<xsl:apply-templates mode="edit" />
请注意,在示例中,如果要使用非模式 xsl:apply-templates 呈现页面的其余部分,则必须显式调用 xsl:template mode="edit" 版本才能编辑特定的 paragraph 元素。
如果您不需要对所有 XML 元素进行模式匹配,请提供一个空模板,例如:
<xsl:template match="*" mode="edit" />
确保您不会从污染输出的深度匹配中获得“幻影”文本。
与任何 xsl 包罗万象的模板一样,将其放在所有 xsl:templates 的开头以获得相同的模式,因为 xsl 仅使用最后一个匹配的模板,并将其放在最后将确保什么都看不到!
【讨论】: