На ваши вопросы:
Есть ли способ разорвать оператор for for each, если условие истинно?
Нет, и обычно это тоже не нужно. XSLT не является обязательным языком программирования, и императивные подходы здесь не очень хорошо работают.
То, что вы, казалось бы, хотите сделать, это выразить "найти первое <LeafNode>
, где @Type='ABC'
, и вернуть true или false в зависимости от того, существует ли он.
Способ сделать это на традиционных языках подобен вашему подходу: для каждого узла проверьте условие, если условие выполнено, затем вернитесь.
В XSLT вы просто выбираете узел с XPath:
//RootNode/LeafNode[@Type='ABC']
либо результат этого содержит узел, либо его нет. Нет необходимости для каждого на всех.
Можем ли мы использовать значение переменной Template или param из основной вызывающей подпрограммы?
Нет. Переменные и параметры строго ограничены. Они выходят из области видимости после обработки, оставляя их родительский элемент. Они также являются постоянными, как только они объявлены, они не могут быть изменены.
Способ сделать то, что вы хотите здесь, это сделать шаблон вывести желаемое значение и записать его в переменную:
<xsl:template>
<xsl:variable name="returnValue">
<xsl:call-template name="TestTemplate" />
</xsl:variable>
</xsl:template>
<xsl:template name="TestTemplate">
<!-- the following expression emits true or false -->
<xsl:value-of select="
count(//RootNode/LeafNode[@Type='ABC']) gt; 0
" />
</xsl:template>
Два последних совета:
- Избегайте оператора
'//'
любой ценой. Большую часть времени его использование не является необходимым
- первый, самый верхний элемент в документе - это не «корневой узел», это «элемент документа»
Это важное различие. «Корневой узел» ставится перед элементом документа, поэтому приведенный выше XPath должен выглядеть примерно так (семантически):
/DocumentElement/LeafNode
^------ *this* slash represents the "root node"