我有模板
<xsl:template match="node" mode="some_mode">
<xsl:value-of select="child1" />
<xsl:value-of select="child2" />
<xsl:value-of select="child3" />
</xsl:template>
我想应用模板,以便在一个案例中选择模板中指定的所有节点,如
<xsl:apply-templates select="node" mode="some_node" /> <!-- select all inside the node tag -->
在另一种情况下我想限制输出,例如不要选择&lt; child1&gt;或&lt; child2&gt;节点。我可以用变量或参数做到吗?或者我是否必须从头开始编写另一个模板?
<xsl:apply-templates select="node" mode="some_node" /> <!-- select only some tags from the node tag -->
换句话说,我会多次使用这个模板,我想在申请时控制输出。我可以定义变量,但文档说我无法在定义变量后更改变量的值。可能这个参数会被贬低,但我对此并不擅长。
答案 0 :(得分:1)
使用模板中的xsl:if指令进行分支。
示例:
<xsl:template match="node">
<xsl:value-of select="child1" />
<xsl:if test="price > 10">
<xsl:value-of select="child2" />
<xsl:value-of select="child3" />
</xsl:if>
</xsl:template>
我希望在这个问题中有一个简单的例子。从表面看来,我不会在这里做一个简单的例子,它会解决你的问题,并向你展示xsl:if指令是如何完美的答案。
假设你有这样的音乐收藏......
<?xml version="1.0"?>
<catalog>
<cd>
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
<cd>
<title>Hide your heart</title>
<artist>Bonnie Tyler</artist>
<country>UK</country>
<company>CBS Records</company>
<price>9.90</price>
<year>1988</year>
</cd>
</catalog>
并且您想要输出CD的列表标题和价格的html表。通常你想要标题和价格,但在某些条件下(比如价格低于10美元),你想要抑制价格的输出,只需要一些静态文本,比如“便宜10.00”。
所以你的预期输出应该是:
<?xml version="1.0" encoding="utf-8"?>
<table>
<tr>
<td>Empire Burlesque</td>
<td>cheaper than 10.00</td>
</tr>
<tr>
<td>Hide your heart</td>
<td>9.90</td>
</tr>
</table>
产生此转换的样式表可以是:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<table>
<xsl:apply-templates select="//cd"/>
</table>
</xsl:template>
<xsl:template match="cd">
<tr>
<td><xsl:value-of select="title"/></td>
<xsl:if test="price < 10">
<td><xsl:value-of select="price"/></td>
</xsl:if>
<xsl:if test="not(price < 10)">
<td>cheaper than 10.00</td>
</xsl:if>
</tr>
</xsl:template>
</xsl:stylesheet>
并且您有完美的答案 - 如何根据条件应用整个模板或仅部分模板。在这种情况下,条件是价格低于10美元。
答案 1 :(得分:1)
如果不修改你的模板,我担心这是不可能的。
您可以考虑将模板输出存储在变量中,然后对其进行处理以删除child1
和child2
值。但我想您无法猜测输出的哪一部分来自child1
和/或child2
。
或者您可以开发另一个执行该替代操作的模板。
编辑:另一个想法:在应用模板之前,也许可以应用过滤去掉child1
和child2
(这将是一种多遍XSL转换)。
答案 2 :(得分:1)
我建议使用具有不同匹配模式和/或不同模式的单独模板。这是首选使用条件,因此编写凌乱和潜在的错误代码:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:apply-templates mode="allChildren"/>
==========
<xsl:apply-templates mode="child3Only"/>
</xsl:template>
<xsl:template match="node" mode="allChildren">
<xsl:copy-of select="*"/>
</xsl:template>
<xsl:template match="node" mode="child3Only">
<xsl:copy-of select="child3"/>
</xsl:template>
</xsl:stylesheet>
将此转换应用于以下文档(类似于您在上一个问题中使用的转换):
<document>
<node>
<child1>Child 1</child1>
<child2>Child 2</child2>
<child3>Child 3</child3>
</node>
<anotherNode />
</document>
生成了想要的结果:
<child1>Child 1</child1><child2>Child 2</child2><child3>Child 3</child3>
==========
<child3>Child 3</child3>