【问题标题】:XSLT 3.0 partial streaming (Saxon)XSLT 3.0 部分流式传输 (Saxon)
【发布时间】:2014-12-03 05:53:37
【问题描述】:

我有一个包含这种树的大 XML 文件(6 GB):

<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(),我可以直接在for-each (like in this question) 中使用多个xsl:value-of。 (否则我有这个错误* There are at least two consuming operands: {xsl:value-of} on line 8, and {xsl:value-of} on line 9

但我仍然有流媒体限制,因为&lt;xsl:call-template name="fnc1"/&gt; 会产生此错误:

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)?

感谢您的帮助!

【问题讨论】:

  • 您是否考虑过不声明&lt;xsl:mode streamable="yes" /&gt;,而是使用&lt;xsl:template name="main"&gt;&lt;xsl:stream href="foo.xml"&gt;&lt;xsl:apply-templates select="Report/Document/copy-of()"/&gt;&lt;/xsl:stream&gt;&lt;/xsl:template&gt;,然后您应该能够使用任何命名和/或匹配的模板来处理Document元素节点及其后代,例如&lt;xsl:template match="Document"&gt;DOC HEADER document type&gt;&lt;xsl:value-of select="documentType"/&gt;...&lt;xsl:call-template name="fcn1"/&gt;DOC FOOTER&gt;&lt;/xsl:template&gt;?
  • 我用流尝试了一些东西,但我遇到了同样的错误。现在使用apply-templates 超过copy-of() 的技巧会给出错误Fatal error during transformation: java.lang.RuntimeException: Internal error evaluating template at line 4

标签: xml xslt streaming saxon xslt-3.0


【解决方案1】:

我认为当上下文项接地(即不是流式节点)时,调用模板应该是可流式的,因此我会将其视为错误。同时,一种解决方法可能是将 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 版本中的任何不必要的偏离视为错误,除非修复它们会破坏产品的稳定性。

【讨论】:

  • 非常感谢,它运行良好,性能也不错(输入 6.4GB,输出 1.2GB,处理时间 4 分钟)。只是有点语法错误,我们需要匹配属性:&lt;xsl:template name="fnc1" mode="fnc1" match="Document"/&gt;。 (我试图编辑你的答案,但我不知道不知道该主题的人可以拒绝该版本,感谢@tylerk @littlebobbytables @dmitry-fucintv ;)
  • 感谢产品反馈,xsl:call-template 现在可以在这种情况下进行流式传输。
猜你喜欢
  • 1970-01-01
  • 2021-11-15
  • 2021-01-01
  • 2011-12-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-21
  • 1970-01-01
相关资源
最近更新 更多