谁能给我一个xsl中模板“模式”的例子吗?
Posted
技术标签:
【中文标题】谁能给我一个xsl中模板“模式”的例子吗?【英文标题】:Can one give me the example for "mode" of template in xsl? 【发布时间】:2011-05-28 01:50:40 【问题描述】:在
<xsl:template name="temp_name" mode="mode">
mode
是什么意思?我搜索了很多资源,但找不到示例。那么有人可以举个例子来解释一下吗?
【问题讨论】:
【参考方案1】:给模板命名和模式并没有太大意义。
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
能够被动态定义,哪种类型的使用会受益。
@Patanjali,还有其他更好的方法来动态选择处理。在 XSLT 1.0 或 2.0 中,可以使用 FXSL 库进行 XSLT 函数式编程(请参阅fxsl.sf.net)。在 XPath 3 (XSLT 3.0) 中,可以将函数作为参数传递给其他函数,即函数项是第一类对象,高阶函数是该语言的标准特性
不幸的是,我仅限于使用 XSLT 1.0,因为它是 php 提供的全部,而且我的目标受众主要使用 cPanel 和共享服务器,因此无法添加此类扩展。但是,PHP 允许从 XSLT 调用内置的和程序员定义的 PHP 函数,这可能提供比任何扩展所允许的更丰富的环境。总有一种方法可以完成工作,而限制只会迫使我们发挥创造力。
Dimitre,你澄清了我对 mode
的误解。
@Patanjali,FXSL 不是扩展——它是用纯 XSLT 1.0 编写的。有不同的版本——用于 XSLT 1.0 和 XSLT 2.0。【参考方案2】:
<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
【讨论】:
这个答案主要是从 XSLT 袖珍指南中复制和粘贴的信息。 OP要求有人用例子来解释它...... 模板作为函数,这里的例子简洁地演示了名为“phone”的类似OO的多态函数。你可以给不同的模式打电话给不同的电话。 这个例子的问题在于,虽然它可以证明它,但它需要知道像 OP 之类的问题在能够理解之前所寻求的知识。这正是我发现很多 MS 文档没有帮助的原因。但是,因为它没有讨论它如何使用mode
,所以这里不应该不解释就提供它。【参考方案3】:
mode
属性允许以多种方式处理相同的 XML 元素。
如果要使用mode
属性,模板必须具有match
属性,因此它们不适用于仅依赖name
属性进行调用的模板。
它们应用到xsl:apply-templates
以确定哪个xsl:template
s 将响应,因此使用模式的应用只会调用使用相同模式的模板。没有模式的模板只会响应没有模式的应用。
例如,您可能希望将 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:template
s 的开头以获得相同的模式,因为 xsl 仅使用最后一个匹配的模板,并将其放在最后将确保什么都看不到!
【讨论】:
以上是关于谁能给我一个xsl中模板“模式”的例子吗?的主要内容,如果未能解决你的问题,请参考以下文章