Я полагаю, что мое подозрение было верным: вы переходите к своему предложению <xsl:otherwise>
, когда $string
имеет значение, а $delimiter
нет, вызывая бесконечный цикл, как вы говорите.
Добавьте следующее новое предложение <xsl:when>
после первого:
<xsl:when test="not($delimiter) and $string = ''" />
Это не позволит исполнению войти в блок <xsl:otherwise>
, когда это не должно быть.
Более подробное объяснение того, что происходит и почему это происходит:
В блоке <xsl:choose>
есть три ветви.
<xsl:when test="not($delimiter) and $string != ''">
<xsl:when test="contains($string, $delimiter)">
<xsl:otherwise>
Таким образом, когда ни $string
, ни $delimiter
не содержат значений, первое условие не выполняется (поскольку $string != ''
имеет значение false). Второе условие выполняется (потому что contains(nil,nil)
всегда возвращает true (подтверждено в Visual Studio)), что снова вызывает шаблон с теми же параметрами (потому что substring-before
возвращает пустую строку, так как он не содержит пустой разделитель). Ergo, бесконечный цикл.
Исправлено добавление нового пустого условия:
<xsl:when test="not($delimiter) and $string != ''">
<xsl:when test="not($delimiter) and $string = ''" />
<xsl:when test="contains($string, $delimiter)">
<xsl:otherwise>
РЕДАКТИРОВАТЬ: я возился и не могу найти ссылку на определенное поведение contains
, когда второй параметр пуст или ноль. Тесты показали, что движок Microsoft Visual Studio XSLT возвращает true
, когда второй параметр пуст или равен нулю. Я не уверен, является ли это определенным поведением или это должен решать разработчик. У кого-нибудь есть окончательный ответ на этот вопрос? Томалак, я смотрю на тебя.