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

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

<Report>
   <Document>
      <documentType>E</documentType>
      <person>
         <firstname>John</firstname>
         <lastname>Smith</lastname>
      </person>
   </Document>
   <Document>
      [...]
   </Document>
   <Document>
      [...]
   </Document>
   [... there are a lot of Documents]
</Report>

Поэтому я использовал новую потоковую функцию XSLT 3.0 с Saxon 9.6 EE. Я не хочу иметь потоковые ограничения один раз в документе. Вот почему я пытался использовать copy-of(), Я думаю, что то, что я хочу сделать, очень близко к "пакетному режиму", который описан здесь: http://saxonica.com/documentation/html/sourcedocs/streaming/burst-mode-streaming.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:for-each select="/Report/Document/copy-of()" >
           DOC HEADER
           documentType: <xsl:value-of select="documentType"/>
           person/firstname: <xsl:value-of select="person/firstname"/>

           <xsl:call-template name="fnc1"/>

           DOC FOOTER
        </xsl:for-each>
    GLOBAL FOOTER
</xsl:template>

<xsl:template name="fnc1">
    documentType again: <xsl:value-of select="documentType"/>
</xsl:template>

</xsl:stylesheet>

В некотором смысле это работает, потому что с copy-of() Я могу использовать несколько xsl:value-of непосредственно для каждого ( как в этом вопросе). (В противном случае у меня есть эта ошибка * There are at least two consuming operands: {xsl:value-of} on line 8, and {xsl:value-of} on line 9)

Но у меня все еще есть ограничения потоковой передачи, потому что <xsl:call-template name="fnc1"/> создает эту ошибку:

Error at xsl:template on line 4 column 25 of stylesheet.xsl:
  XTSE3430: Template rule is declared streamable but it does not satisfy the streamability rules.
  * xsl:call-template is not streamable in this Saxon release
Stylesheet compilation failed: 1 error reported

Поэтому мой вопрос: как сделать частичную потоковую передачу (документы загружаются один за другим, но полностью), чтобы можно было использовать call-template (и другие apply-templates) в документе?

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

1 ответ

Решение

Я думаю, что call-template должен быть потоковым, когда элемент контекста заземлен (т.е. не является потоковым узлом), поэтому я буду рассматривать это как ошибку. Между тем, временное решение может заключаться в объявлении fnc1 как

<xsl:template name="fnc1" mode="fnc1" match="Document"/>

и назвать это как

<xsl:apply-templates select="." mode="fnc1"/>

В качестве альтернативы замените шаблон функцией и предоставьте элемент контекста в качестве явного аргумента.

Вы можете отследить ошибку здесь:

https://saxonica.plan.io/issues/2171

Хотя мы пока не заявляем о 100% -ном соответствии спецификации XSLT 3.0, мы будем рассматривать любые ненужные отклонения в выпуске 9.6 как ошибки, если только их исправление не приведет к дестабилизации продукта.

Другие вопросы по тегам