Как разбить цикл for-each в XSLT?
Как разбить цикл for-each в XSLT?
Ответ 1
XSLT написан в очень функциональном стиле, и в этом стиле нет эквивалента оператора break
. Что вы можете сделать, это примерно так:
<xsl:for-each select="...nodes...">
<xsl:if test="...some condition...">
...body of loop...
</xsl:if>
</xsl:for-each>
Таким образом, for-each
все равно будет проходить через все узлы, но тело цикла будет выполняться только в том случае, если условие истинно.
Ответ 2
Поместите условие для остановки цикла в атрибуте select
элемента for-each
. Например, "разбить" после четырех элементов:
<xsl:for-each select="nodes[position()<=4]">
Чтобы продолжить, но не включая node, который удовлетворяет определенному условию:
<xsl:for-each select="preceding-sibling::node[condition]">
Ответ 3
XSLT не является процедурным языком; не думайте о том, что каждый из них является "циклом" в том, как у вас есть цикл в Java. Для каждого - способ применения шаблона к каждой из нескольких элементов. Это не обязательно происходит в определенном порядке, поэтому вы не можете думать об этом как "применять этот шаблон к каждому из множества элементов до тех пор, пока это не произойдет, а затем остановится".
Тем не менее, вы можете использовать атрибут select для фильтрации результатов, поэтому он больше похож на "применять шаблон к каждой из кусков элементов, но только если это и так".
Если то, что вы действительно хотите, "примените шаблон к каждой из кусков элементов, где такое-то и верно для них, но только для первого, что это верно", вы можете комбинировать атрибут select с функцией position().
Ответ 4
"Разрыв" из тела инструкции <xsl:for-each>
XSLT не может быть задан с использованием синтаксической конструкции, однако можно моделировать.
Этот фрагмент кода в topxml.com подробно описывает технику:
Если вам нужен "разрыв" из цикла xsl: for-each p >
В основном обсуждаются два метода:
-
Выполнение чего-то внутри тела
<xsl:for-each>
только при выполнении определенного условия. -
Указание обработки, не использующей
<xsl:for-each>
, но с рекурсией
Второй способ имеет преимущество в том, что он может немедленно выполнить выход, что контрастирует с первым методом, который все еще выполняет множество "пустых циклов" даже после того, как условие выхода выполнено.
Ответ 5
Привет, я знаю, это старый пост, но, возможно, он может помочь другим разработчикам. Я нашел способ разбить a для каждого в XSLT, это не litteraly перерыв, но если вы увидите код, вы получите его. Как вы знаете или не знаете, вы можете использовать встроенный код С# в xslt. В этом примере я хочу объединить узлы и взять первый NTE node со значением RC. Но если я получу node, который отличается от NTE node, я хочу перестать смотреть на условие. Поэтому я устанавливаю глобальную переменную в коде С#, и каждый раз, когда я просматриваю node:
я задаю значение, <xsl:value-of select="userCSharp:SetStopForeach('true')" />
<xsl:for-each select="following-sibling::node()">
<xsl:if test="local-name()='NTE_NotesAndComments_3' and userCSharp:GetStopForeach()" >
<xsl:for-each select="NTE_4_CommentType">
<xsl:if test="(CE_0364_0_IdentifierSt)[text()="RC"]">
<ns0:RESULTAAT_COMMENTAAR>
<xsl:for-each select="../NTE_3_Comment">
<xsl:value-of select="./text()" />
</xsl:for-each>
</ns0:RESULTAAT_COMMENTAAR>
</xsl:if>
</xsl:for-each>
</xsl:if>
<xsl:if test="local-name()='ORC_CommonOrder'" >
<xsl:value-of select="userCSharp:SetStopForeach('false')" />
</xsl:if>
</xsl:for-each>
.....
<msxsl:script language="C#" implements-prefix="userCSharp">
<![CDATA[
public bool StopForeach=false;
public bool GetStopForeach() {
return StopForeach;
}
public string SetStopForeach(bool aValue) {
StopForeach=aValue;
return "";
}
]]>
</msxsl:script>
Ответ 6
У меня была аналогичная ситуация, и вот код, который я написал. По логическим причинам я не мог вписаться в другие условия с условием01.
<xsl:for-each select="msxsl:node-set($DATA6)[condition01]">
<xsl:choose>
<xsl:when test="not((condtion02 or condition03) and condition04)">
--body of for loop
</xsl:when>
</xsl:choose>
</xsl:for-each>