Ошибка Saxon9HE XLM0001: слишком много вложенных вызовов apply-templates. Таблица стилей может зацикливаться

Я использую Saxon9HE для преобразования XML 2.0. из класса Java; решение взято из этого более раннего вопроса
Я преобразовываю текст, разделенный двойными чертами, в XML.
Однако некоторые поля содержат резюме людей, и преобразование вызывает ошибку зацикливания, упомянутую в заголовке.

Есть ли способ исправить это? Я читал об увеличении максимальной глубины в стеке шаблонов, но это относится только к Oxygen; есть ли аналогичная настройка в Saxon9HE.jar?

Вот код, вы также можете нажать на ссылку выше, чтобы получить код

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output indent="yes"/>

<xsl:template match="node()|@*">
    <xsl:copy>
        <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="str">
  <xsl:copy>
    <xsl:apply-templates select="@*"/>
    <xsl:analyze-string select="." regex="\|((\|\s*[^|]+\s*\|)+)\|">
      <xsl:matching-substring>
        <xsl:analyze-string select="regex-group(1)" regex="\|\s*(\w+):([^|]+?)\s*\|">
          <xsl:matching-substring>
            <xsl:element name="{regex-group(1)}">
              <xsl:value-of select="regex-group(2)"/>
            </xsl:element>
          </xsl:matching-substring>
        </xsl:analyze-string>
      </xsl:matching-substring>
      <xsl:non-matching-substring>
        <xsl:value-of select="."/>
      </xsl:non-matching-substring>
    </xsl:analyze-string>
  </xsl:copy>
</xsl:template>


</xsl:stylesheet>  

Спасибо,


person djm    schedule 02.08.2013    source источник
comment
Если вы используете Oracle Java, прочтите docs.oracle .com/javase/7/docs/technotes/tools/windows/java.html, он предполагает, что вы можете увеличить пространство стека, используя параметр -Xss командной строки java.exe, с которым вы запускаете свой код Java.   -  person Martin Honnen    schedule 02.08.2013
comment
Я не совсем уверен, вызывает ли это ОП. Я думаю, что если он достигнет предела стека Java, Saxon рухнет - у него не будет возможности пожаловаться на apply-templates?   -  person Vadim Peretokin    schedule 04.08.2013
comment
Я потратил час на гугление и чтение документов Saxon, но не смог найти решение для вас. Может быть проще спросить сообщество Oxygen.   -  person Vadim Peretokin    schedule 04.08.2013
comment
@Vadi, Саксон перехватывает исключение StackOverflow и пытается объяснить его с точки зрения исполняемого кода таблицы стилей.   -  person Michael Kay    schedule 04.08.2013
comment
@Вади; Я не использую Oxygen, просто там я нашел предложение расширить память стека. Извините за путаницу   -  person djm    schedule 04.08.2013


Ответы (1)


Есть две возможности: либо таблица стилей выполняет бесконечную рекурсию, либо она выполняет глубокую рекурсию, которая в конечном итоге завершается, но требует слишком много места в стеке.

Первый шаг — выяснить, какие из них применимы, и мы не можем сделать это, не видя вашего кода.

Если это непрерывная рекурсия, то, очевидно, это ошибка в вашем коде, которую необходимо исправить.

Если это глубокая, но конечная рекурсия, то может быть решение путем увеличения доступных ресурсов, но это зависит от того, насколько вы близки к пределу. Как практическое правило, не пытайтесь выполнить рекурсию более чем на 500 уровней в глубину.

Есть несколько способов переписать код, чтобы избежать глубокой рекурсии:

(a) вы можете воспользоваться оптимизацией хвостового вызова Saxon

(b) вы можете использовать рекурсивный алгоритм «разделяй и властвуй» вместо рекурсии «голова-хвост»

(c) вы можете вообще избежать рекурсии, например, используя xsl:iterate или xsl:analyze-string или функцию fold-left().

Но мы не можем помочь, не видя, что вы пытаетесь сделать. Покажите нам код!

person Michael Kay    schedule 04.08.2013
comment
Вы можете получить код, щелкнув ссылку на предыдущий вопрос, и я добавил код для полноты. - person djm; 04.08.2013
comment
Хорошо, спасибо. Я предполагаю, что проблема возникает не из-за рекурсии на уровне приложения, а из-за рекурсии в механизме регулярных выражений. Способ уменьшить это — попытаться написать регулярное выражение таким образом, чтобы избежать необходимости возврата. Например, во втором регулярном выражении фрагмент ([^|]+?)\s* можно было бы переписать как ([^|\s]+?)\s*. - person Michael Kay; 05.08.2013
comment
Извините, это не сработало. Я получаю ту же ошибку; Ошибка в xsl:apply-templates в строке 7 файла dbl-pipe.xsl: SXLM0001: слишком много вложенных вызовов apply-templates. Таблица стилей может зацикливаться. - person djm; 05.08.2013
comment
Если у вас есть таблица стилей и исходный документ, демонстрирующие проблему, опубликуйте их на saxonica.plan.io, и мы посмотрим, сможем ли мы решить, что происходит, и внести предложения. - person Michael Kay; 05.08.2013
comment
Я создал выпуск №1859. - person djm; 06.08.2013