在xsl中,xsl:apply-imports元素可应用来导入样式表中的模板规则,而一般情况下,我们导入的样式模板规则的优先级会比主样式表中的模板规则的优先级低,所以,当我们想要在主样式表中应用导入的样式表中的模板规则的时候,就可以用apply-imports元素来实现。如果对于某一个元素而言,在多个导入的样式表中都包含其模板规则,则取最近一个模板规则,这个和CSS的应用规则是一样的。
下面用MSDN上的例子来说明(代码稍有变化,但是后面有些疑问,暂时没搞明白,不知哪位仁兄能解释一下):
我们现有一个ops.xml,用来保存计算的基本数据:
<?xml-stylesheet type="text/xsl" href="ops.xslt"?>
<ops>
<desc>
Some Operations Demo
</desc>
<op name="add" symbol="+">
<operand>1</operand>
<operand>2</operand>
</op>
<op name="sub" symbol="-">
<operand>1</operand>
<operand>2</operand>
</op>
<op name="mul" symbol="*">
<operand>1</operand>
<operand>2</operand>
</op>
<result name="result1">
1
</result>
</ops>
主样式表:ops.xslt
<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:import href="agri.xslt"/>
<xsl:import href="str.xslt"/>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="op">
<xsl:value-of select="operand[1]"/>
<xsl:value-of select="@symbol"/>
<xsl:value-of select="operand[2]"/>
= <xsl:apply-imports/>
<br/>
</xsl:template>
</xsl:stylesheet>
另外还有两个辅助的被导入的样式表:
agri.xslt
<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="xml" indent="yes"/>
<xsl:template match="op[@symbol='+']">
<xsl:value-of select="sum(operand)"/> (from agri.xslt)
</xsl:template>
<xsl:template match="op[@symbol='-']">
<xsl:value-of select="number(operand[1])-number(operand[2])"/> (from agri.xslt)
</xsl:template>
<xsl:template match="op[@symbol='*']">
<xsl:value-of select="number(operand[1])*number(operand[2])"/> (from agri.xslt)
</xsl:template>
<xsl:template match="result">
<xsl:value-of select="."/>
</xsl:template>
</xsl:stylesheet>
以及 str.xslt
<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="xml" indent="yes"/>
<xsl:template match="desc">
<DIV>
<xsl:value-of select="."/>
</DIV>
</xsl:template>
<xsl:template match="op[@name='add']">
<xsl:value-of select="operand[1]"/>
<xsl:value-of select="operand[2]"/>
(from str.xslt)
</xsl:template>
<xsl:template match="op[@name='mul']">
<xsl:value-of select="operand[2]"/>
<xsl:value-of select="operand[1]"/>
(from str.xslt)
</xsl:template>
</xsl:stylesheet>
从agri.xslt和str.xslt两个代码,不难看出 agri.xslt 是算术计算两个操作数,而 str.xslt 是字符串连接操作两个操作数,运行结果如下:
1+2 = 12 (from str.xslt)
1-2 = -1 (from agri.xslt)
1*2 = 21 (from str.xslt)
1
从结果我们可以看出来,str.xslt中定义的 "op[@name='add']" 和 "op[@name='mul']" 覆盖了 agri.xslt 中定义的规则。
疑问一:在主样式表 ops.xslt 中,我们的模板match 的是 op 节点(match = "op"),而
"Some Operations Demo"这个显示结果应该是 str.xslt中定义的,但定义的节点是 Desc节点,在 op节点外面,这个为啥会显示出来呢??
同样,最后一行的 "1"应该是 agri.xslt中定义的,也是在op节点外的 ???
接着,我将主样式表稍微做了点修改
ops1.xslt
<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:import href="agri.xslt"/>
<xsl:import href="str.xslt"/>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<xsl:apply-imports/>
<xsl:for-each select="ops/op">
<xsl:apply-templates select="."></xsl:apply-templates>
</xsl:for-each>
</xsl:template>
<xsl:template match="op">
<xsl:value-of select="operand[1]"/>
<xsl:value-of select="@symbol"/>
<xsl:value-of select="operand[2]"/>
=
<br/>
</xsl:template>
</xsl:stylesheet>
我将 match="op" 作为一个单独的模板,并且在主模板 match="/" 中 应用 xsl:apply-templates 将 match="op" 应用过来,并且在 for-each 操作之前,先 应用导入的模板规则,这样显示的结果却如下:
结果二:
1+2 =
1-2 =
1*2 =
1 1+2 =
1-2 =
1*2 =
从运行结果可以看出,for-each 规则运行了两遍 ??? 这个结果我没有搞明白,希望哪位能解释下??
还有一种情况,我将主样式表更改如下:
ops2.xslt:
<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:import href="agri.xslt"/>
<xsl:import href="str.xslt"/>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<xsl:apply-templates select="ops/op"></xsl:apply-templates>
</xsl:template>
<xsl:template match="op">
<xsl:value-of select="operand[1]"/>
<xsl:value-of select="@symbol"/>
<xsl:value-of select="operand[2]"/>
= <xsl:apply-imports/>
<br/>
</xsl:template>
</xsl:stylesheet>
我把主样式表中主模板规则的match和for-each的XPath表达式稍微做了点修改(参照ops.xslt),而这次的结果却为:
结果三:
1-2 = -1 (from agri.xslt)
1*2 = 21 (from str.xslt)
这个时候却没有了 op节点以外的其它节点的样式了。
疑问二:从上面三个不同xslt的写法,得出三个不同的结果,说明apply-imports的执行(最主要是非主模板规则节点:像上面的Desc和Result节点)与主模板规则的Select 或者Match 表达式有很大的关系,但是具体存在什么关系,为什么是这样的,我一直没有搞清楚,哪位知道的仁兄能解释下!!
谢谢!!