xml XSL - 如何判断元素是否是最后一个系列

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2817664/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-06 13:06:13  来源:igfitidea点击:

XSL - How to tell if element is last in series

xmlxslt

提问by Chris

I have an XSL template that is selected for execution (below). What I would like to do is be able to tell if I am the last Unitbeing matched.

我有一个选择执行的 XSL 模板(如下)。我想做的是能够判断我是否是最后一个Unit被匹配的人。

  <xsl:template match="Unit[@DeviceType = 'Node']">
    <!-- Am I the last Unit in this section of xml? -->
    <div class="unitchild">
      Node: #<xsl:value-of select="@id"/>
    </div>
  </xsl:template>

Example XML

示例 XML

<Unit DeviceType="QueueMonitor" Master="1" Status="alive" id="7">
    <arbitarytags />
    <Unit DeviceType="Node" Master="0" Status="alive" id="8"/>
    <Unit DeviceType="Node" Master="0" Status="alive" id="88"/>
</Unit>

采纳答案by Mads Hansen

If you want to test whether it is the last Unit element at the same level (with the same parent element), even if there are arbitrary tags before, after, and in-between then this would work:

如果要测试它是否是同一级别的最后一个 Unit 元素(具有相同的父元素),即使之前、之后和中间有任意标签,也可以这样做:

<xsl:if test="not(following-sibling::Unit)">

However, if you are applying templates for a subset, the last in the document may not be in the set being processed. For that, you can test if the position() = last()

但是,如果您正在为子集应用模板,则文档中的最后一个可能不在正在处理的集合中。为此,您可以测试position() = last()

<xsl:if test="position() = last()">

回答by Dimitre Novatchev

The currently selected answer is generally incorrect!

当前选择的答案通常是不正确的!

<xsl:if test="not(following-sibling::Unit)">
<xsl:if test="not(following-sibling::Unit)">

This Will not work with any XML document and any <xsl:apply-templates>

这不适用于任何 XML 文档和任何 <xsl:apply-templates>

The original question is about the last Unitbeing matched, not the last sibling! Which is the last Unit being matched depends only on the expression in the select attribute of <xsl:apply-templates>, not on the physical properties of the XML document.

最初的问题是关于最后一个Unit匹配,而不是最后一个兄弟姐妹!匹配的最后一个 Unit 仅取决于 的 select 属性中的表达式<xsl:apply-templates>,而不取决于 XML 文档的物理属性。

The way to do it:

这样做的方法

<xsl:apply-templates select="SomeExpression"/>

then in the template that matches nodes selected by SomeExpression:

然后在匹配由 选择的节点的模板中SomeExpression

<xsl:if test="position() = last()">
. . . . 
</xsl:if>

This checks if the current node is the last in the node-listselected by <xsl:apply-templates>, not that the current node is the last sibling. This answers exactly the original question.

这会检查当前节点是否是node-listselected by 中的最后一个<xsl:apply-templates>,而不是当前节点是最后一个兄弟节点。这完全回答了最初的问题。

If the question was framed in a different way, asking how to recognize if the last sibling Unitis the current node, then the best solution would be to specify a separate template for this last sibling node:

如果问题以不同的方式提出,询问如何识别最后一个兄弟Unit节点是否是当前节点,那么最好的解决方案是为最后一个兄弟节点指定一个单独的模板:

<xsl:template match="Unit[last()]">
    . . . . 
</xsl:template>

Do note, that in this case there is no need to write any conditional logic inside a template to test if the current node is "the last".

请注意,在这种情况下,无需在模板中编写任何条件逻辑来测试当前节点是否为“最后一个”。

回答by shabunc

You should test position() = last(), but you should test it in predicate, not in the body of the template:

你应该测试 position() = last(),但你应该在谓词中测试它,而不是在模板的主体中:

<?xml version="1.0" encoding="utf-8"?>

<data>
    <item group="B">AAA</item>
    <item>BBB</item>
    <item group="B">CCC</item>
    <item>DDD</item>
    <item group="B">EEE</item>
    <item>FFF</item>
</data>


    <?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:template match="data">
    <xsl:apply-templates select="item[@group]"/>
</xsl:template>

<xsl:template match="item">
    ITEM
    <xsl:if test="position() = last()">
    LAST IN CONTEXT
    </xsl:if>
</xsl:template>

<xsl:template match="item[position() = last()]">
    LAST ITEM
</xsl:template>

回答by Oded

You can test position()against last():

你可以测试position()反对last()

<xsl:template match="Unit[@DeviceType = 'Node']">
 <!-- Am I the last Unit in this section of xml? -->     
 <xsl:if test="position() = last()">
   <!-- Yes I am! -->
   Last Unit
 </xsl:if>

 <div class="unitchild">
  Node: #<xsl:value-of select="@id"/>
 </div>
</xsl:template>

See w3schools article on xsl:if.

请参阅 w3schools 上的文章xsl:if