Частичная потоковая передача 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 как ошибки, если только их исправление не приведет к дестабилизации продукта.