XSLT 3.0 потоковая передача (Saxon)

У меня есть большой XML-файл (6 ГБ) с таким деревом:

<Report>
   <Document>
      <documentType>E</documentType>
      <person>
         <firstname>John</firstname>
         <lastname>Smith</lastname>
      </person>
   </Document>
   <Document>
      [...]
   </Document>
   <Document>
      [...]
   </Document>
   [...]
</Report>

Если я применяю к нему таблицу стилей XSLT, у меня возникает такая ошибка:

Исключение в потоке "main" java.lang.OutOfMemoryError: пространство кучи Java

Итак, я хотел попробовать новую функцию XSLT 3.0: потоковую передачу с Saxon 9.6 EE. Я не хочу иметь ограничения потоковой передачи один раз в документе. Я думаю, что то, что я хочу сделать, очень близко к "пакетному режиму", описанному здесь: http://saxonica.com/documentation/html/sourcedocs/streaming/burst-mode-streaming.html.

Вот моя командная строка Saxon:

java -cp saxon9ee.jar net.sf.saxon.Transform -t -s: input.xml -xsl: stylesheet.xsl -o: output / output.html

Вот моя таблица стилей XSLT:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0">
<xsl:mode streamable="yes" />

<xsl:template match="/">
    GLOBAL HEADER
        <xsl:iterate select="copy-of()/Report/Document" >
           DOC HEADER
           documentType: <xsl:value-of select="documentType"/>
           person/firstname: <xsl:value-of select="person/firstname"/>
           DOC FOOTER
           <xsl:next-iteration/>
        </xsl:iterate>
    GLOBAL FOOTER
</xsl:template>

</xsl:stylesheet>

Но у меня все еще такая же ошибка нехватки памяти.

Спасибо за помощь!


person steco    schedule 06.10.2014    source источник


Ответы (1)


Ваша copy-of () копирует элемент контекста, которым является весь документ. Ты хочешь

copy-of(/Report/Document)

который копирует каждый документ по очереди. Или я склонен писать это

/Report/Document/copy-of()

потому что я думаю, это проясняет то, что происходит.

Между прочим, вам не нужен xsl: iterate здесь: xsl: for-each отлично справится с этой задачей, потому что обработка одного документа не зависит от обработки каких-либо предыдущих документов.

person Michael Kay    schedule 07.10.2014
comment
Спасибо! / Report / Document / copy-of () работает хорошо. Сложность заключается в том, что copy-of (/ Report / Document) выдает эту ошибку: XPTY0004: последовательность из более чем одного элемента не допускается в качестве первого аргумента copy-of () - person steco; 07.10.2014
comment
Функция копирования была изменена в рабочем проекте xslt 3.0 от 2 октября 2014 года, чтобы принимать последовательность узлов, и Saxon 9.6 реализовал это изменение. Вы уверены, что используете 9.6? Я настоятельно рекомендую перейти на Saxon 9.6, если вы занимаетесь стримингом. - person Michael Kay; 07.10.2014
comment
О, вы правы, я нажал не ту ссылку для скачивания. Я использовал Saxon-EE 9.5.1.6J, теперь с Saxon-EE 9.6.0.1J он работает! У меня есть еще одна проблема, связанная с этим пакетным режимом: если я хочу использовать xsl:call-template в тегах xsl:iterate, у меня появляется эта ошибка: XTSE3430: Template rule is declared streamable but it does not satisfy the streamability rules. * xsl:call-template is not streamable in this Saxon release. Есть идеи, как преодолеть ограничения потоковой передачи после копирования? - person steco; 07.10.2014
comment
Пожалуйста, отправьте новый вопрос по этому поводу. Цитируйте код шаблона, который считается нереализуемым. - person Michael Kay; 08.10.2014
comment
Вот он: stackoverflow.com/questions/ 26259139 / - person steco; 08.10.2014