2014-10-08 46 views
0

我有这种树的大XML文件(6 GB): XSLT 3.0部分流(撒克逊)

<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流功能,与撒克逊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

但我仍然有流约束,因为<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)?

谢谢你的帮助!

+0

您是否考虑过不声明'',而是使用'< xsl:apply-templates select =“Report/Document/copy-of()”/>'然后您应该可以使用任何命名和/或匹配的模板来处理'Document'元素节点和它的后代如 DOC HEADER文档类型> ... DOC FOOTER>'? – 2014-10-08 14:26:09

+0

我尝试了一些流,但我有同样的错误。现在你用'apply-templates'的技巧来覆盖'copy-of()',它会给出一个错误:转换期间发生致命错误:java.lang.RuntimeException:第4行的内部错误评估模板 – steco 2014-10-08 14:59:30

回答

0

我认为呼叫模板应该在上下文项目接地时(例如不是流式节点)流式传输,所以我会将其视为一个错误。与此同时,一个解决办法可能是申报FNC1作为

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

和或者称其为

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

,替换函数模板,并提供上下文项目作为一个明确的说法。

你可以在这里跟踪bug:

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

虽然我们不主张用XSLT 100%符合3.0规范,我们会将在9.6版本中加入任何不必要的偏离,除非错误修复它们会破坏产品的稳定性。

+0

非常感谢运行良好,性能也很好(输入6.4GB,输出1.2GB,处理时间4分钟)。只有一点语法错误,我们需要match属性:''。(我试图编辑你的答案,但我不知道不知道该主题的人可以拒绝该版本,这要感谢@tylerk @littlebobbytables @ dmitry-fucintv;)) – steco 2014-10-08 18:39:38

+0

感谢产品反馈,xsl:call在这种情况下模板现在可以流动。 – 2014-10-08 19:36:24