我想选择" abstract"或"身体"标签包含但使用下面的代码我从XSLT中的两个标签获取内容。如果我删除" xsl:if"对输出没有影响。
<xsl:template match="document">
<xsl:for-each select="./child::node()">
<xsl:choose>
<xsl:when test="name() = 'abstract'">
<xsl:call-template name="abstract"/>
</xsl:when>
<xsl:otherwise>
<xsl:if test="name() = 'body'">
<xsl:call-template name="body"/>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
我必须在上面的代码中做出哪些更改?
答案 0 :(得分:0)
将条件移到for-each
之外<xsl:template match="document">
<xsl:choose>
<xsl:when test="abstract">
<xsl:for-each select="abstract">
<xsl:call-template name="abstract"/>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<xsl:for-each select="body">
<xsl:call-template name="body"/>
</xsl:for-each>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
我们首先测试是否有任何抽象元素。如果是这样,我们遍历所有抽象元素并调用适当的模板。
否则,我们遍历body元素并调用相应的模板。
现有的xsl循环遍历所有节点,每个节点检查节点名称,然后应用适当的模板。测试应用于各个节点。没有检查文档内容。
这里的不同之处在于,我们首先测试文档中存在哪些节点,然后仅对我们感兴趣的节点进行循环。
替代方法
假设名为abstract的模板仅处理抽象节点,而名为body的模板仅处理体节点,则更常见的是使用匹配模板而不是命名模板,这将允许我们避免for-each循环
<xsl:template match="document">
<xsl:choose>
<xsl:when test="abstract">
<xsl:apply-templates select="abstract"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="body"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="abstract">
<!-- Process abstract node here -->
</xsl:template>
<xsl:template match="body">
<!-- Process body node here -->
</xsl:template>