有没有办法优化此代码。
<xsl:choose>
<xsl:when test="val1 = val2">
<xsl:apply-templates select="node"/>
</xsl:when>
<xsl:otherwise>
<div>
<xsl:apply-templates select="node"/>
</div>
</xsl:otherwise>
</xsl:choose>
我不喜欢写两次相同的<xsl:apply-templates select="node"/>
。
更新
这个想法是根据比较的结果来做两件事的一个:
只需打印一些信息(我们在应用模板<xsl:apply-templates select="node"/>
后获得)。
打印相同的信息,但事先在容器中“打包”(例如div
)。
答案 0 :(得分:0)
使用强>:
<xsl:apply-templates select="node">
<xsl:sort select="not(val1 = val2)"/>
</xsl:apply-templates>
这是一个完整的例子。这种转变:
<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="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*">
<t>
<xsl:apply-templates select="node">
<xsl:sort select="not(val1 = val2)"/>
</xsl:apply-templates>
</t>
</xsl:template>
<xsl:template match="node[not(val1 = val2)]">
<div>
<node>
<xsl:apply-templates/>
</node>
</div>
</xsl:template>
</xsl:stylesheet>
应用于此XML文档时:
<t>
<node>
<val1>1</val1>
<val2>2</val2>
</node>
<node>
<val1>3</val1>
<val2>3</val2>
</node>
</t>
产生想要的正确结果:
<t>
<node>
<val1>3</val1>
<val2>3</val2>
</node>
<div>
<node>
<val1>1</val1>
<val2>2</val2>
</node>
</div>
</t>
解决方案说明:
每当<xsl:apply-templates>
有一个<xsl:sort>
子项时,所选的节点将根据<xsl:sort>
子项(ren)中提供的数据进行排序,并在每个选定的项目上应用模板的结果节点以该(排序)顺序出现在输出中 - 而不是按文档顺序。
在上面的转型中我们有:
<xsl:apply-templates select="node">
<xsl:sort select="not(val1 = val2)"/>
</xsl:apply-templates>
这意味着将模板应用于名为node
的元素的结果,val1=val2
将在将模板应用于名为node
的元素的结果之前出现val1=val2
不是真的。这是因为false
在true
之前排序。
如果此说明不明确,请读者阅读有关<xsl:sort>
的更多信息。
答案 1 :(得分:0)
这个简单的例子很难实现,但如果包装代码和重复代码的数量值得打扰,你有两个选择:
引入一系列具有不同模式的模板:
<!-- instead of choose -->
<xsl:apply-template match="." mode="container" />
...
<xsl:template match="container" mode="container">
<xsl:apply-templates select="." mode="dup-group"/>
</xsl:template>
<xsl:template match="container[val1=val2]" mode="container">
<div>
<xsl:apply-templates select="." mode="dup-group"/>
</div>
</xsl:template>
<xsl:template match="container" mode="dup-group">
<xsl:apply-templates select="node"/>
<!-- other duplicate code -->
...
</xsl:template>
将部分代码移动到单独的导入样式表中,并覆盖当前样式表中的模板规则:
<xsl:template match="container[val1=val2]">
<div>
<xsl:apply-imports />
</div>
</xsl:template>
答案 2 :(得分:-1)
您在此处发布的xslt不是很优化。如果您不想复制的代码超过两行,则可以通过创建命名模板并调用它来进行优化。在这个例子中,它确实没有多大意义,但你会明白这个想法:
<xsl:when test="val1=val2">
<xsl:call-template name="optimized"/>
</xsl:when>
<xsl:otherwise>
<div>
<xsl:call-template name="optimized"/>
</div>
</xsl:otherwise>
模板:
<xsl:template name="optimized">
<xsl:apply-templates select="node"/>
</xsl:template>
被调用的模板与调用代码位于相同的上下文中,因此您只需将不想复制的代码复制到命名模板即可。