Project

Profile

Help

Problem with copy-of() and apply-templates and last(): causes internal error java.lang.UnsupportedOperationException: last() cannot be used when streaming

Added by Martin Honnen over 4 years ago

I have run into a problem using <xsl:apply-templates select="current-group()!copy-of()" mode="some-mode"/> and then using last() in a template for that mode which is not declared as streamable, for some reasons I don't understand Saxon 9.9.1.5 EE runs the stylesheet but then gives an internal error:

java.lang.UnsupportedOperationException: last() cannot be used when streaming
        at net.sf.saxon.tree.iter.ManualIterator.getLength(ManualIterator.java:114)
        at net.sf.saxon.expr.XPathContextMinor.getLast(XPathContextMinor.java:237)
        at net.sf.saxon.functions.PositionAndLast$Last.evaluateItem(PositionAndLast.java:150)
        at net.sf.saxon.functions.PositionAndLast.call(PositionAndLast.java:126)
        at net.sf.saxon.functions.PositionAndLast$Last.call(PositionAndLast.java:148)
        at net.sf.saxon.expr.FunctionCall.iterate(FunctionCall.java:532)
        at net.sf.saxon.expr.Expression.evaluateItem(Expression.java:846)
        at net.sf.saxon.expr.CompareToIntegerConstant.effectiveBooleanValue(CompareToIntegerConstant.java:178)
        at net.sf.saxon.expr.instruct.Choose.choose(Choose.java:918)
        at net.sf.saxon.expr.instruct.Choose.evaluateItem(Choose.java:946)
        at net.sf.saxon.functions.ScalarSystemFunction$1.evaluateItem(ScalarSystemFunction.java:80)
        at net.sf.saxon.functions.ScalarSystemFunction$1.evaluateItem(ScalarSystemFunction.java:76)
        at net.sf.saxon.functions.Concat$1.evaluateAsString(Concat.java:92)
        at net.sf.saxon.functions.Concat$1.evaluateItem(Concat.java:102)
        at net.sf.saxon.expr.instruct.ComputedElement.getElementName(ComputedElement.java:289)
        at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:316)
        at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:299)
        at net.sf.saxon.expr.instruct.TemplateRule.applyLeavingTail(TemplateRule.java:352)
        at net.sf.saxon.expr.instruct.TemplateRule.apply(TemplateRule.java:315)
        at com.saxonica.ee.stream.feed.ApplyTemplatesFeed.processItem(ApplyTemplatesFeed.java:77)
        at com.saxonica.ee.stream.feed.NoOpenOrCloseFeed.processItem(NoOpenOrCloseFeed.java:36)
        at net.sf.saxon.tree.iter.SingletonIterator.forEachOrFail(SingletonIterator.java:152)
        at com.saxonica.ee.stream.feed.ItemFeed.processItems(ItemFeed.java:68)
        at com.saxonica.ee.stream.feed.AbsorptionFeed.endSelectedParentNode(AbsorptionFeed.java:81)
        at com.saxonica.ee.stream.watch.Trigger.endSelectedParentNode(Trigger.java:98)
        at com.saxonica.ee.stream.watch.WatchManager.endElement(WatchManager.java:497)
        at net.sf.saxon.event.StartTagBuffer.endElement(StartTagBuffer.java:308)
        at com.saxonica.ee.stream.ContentDetector.endElement(ContentDetector.java:56)
        at net.sf.saxon.event.Stripper.endElement(Stripper.java:169)
        at net.sf.saxon.event.ReceivingContentHandler.endElement(ReceivingContentHandler.java:528)
        at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.endElement(AbstractSAXParser.java:609)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanEndElement(XMLDocumentFragmentScan
nerImpl.java:1782)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocument
FragmentScannerImpl.java:2967)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:602)
        at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:112)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScanne
rImpl.java:505)
        at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:842)
        at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:771)
        at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
        at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213)
        at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:643)
        at net.sf.saxon.event.Sender.sendSAXSource(Sender.java:435)
        at net.sf.saxon.event.Sender.send(Sender.java:167)
        at net.sf.saxon.trans.XsltController.applyStreamingTemplates(XsltController.java:1050)
        at net.sf.saxon.s9api.AbstractXsltTransformer.applyTemplatesToSource(AbstractXsltTransformer.java:339)
        at net.sf.saxon.s9api.Xslt30Transformer.applyTemplates(Xslt30Transformer.java:311)
        at net.sf.saxon.Transform.processFile(Transform.java:1283)
        at net.sf.saxon.Transform.doTransform(Transform.java:815)
        at net.sf.saxon.Transform.main(Transform.java:80)
java.lang.RuntimeException: Internal error evaluating template rule  at line 22 in module file:/C:/Users/marti/OneDrive/
Documents/xslt/blog-xslt-3-by-example/add-positional-index/./sheet3.xsl
        at net.sf.saxon.expr.instruct.TemplateRule.applyLeavingTail(TemplateRule.java:371)
        at net.sf.saxon.expr.instruct.TemplateRule.apply(TemplateRule.java:315)
        at com.saxonica.ee.stream.feed.ApplyTemplatesFeed.processItem(ApplyTemplatesFeed.java:77)
        at com.saxonica.ee.stream.feed.NoOpenOrCloseFeed.processItem(NoOpenOrCloseFeed.java:36)
        at net.sf.saxon.tree.iter.SingletonIterator.forEachOrFail(SingletonIterator.java:152)
        at com.saxonica.ee.stream.feed.ItemFeed.processItems(ItemFeed.java:68)
        at com.saxonica.ee.stream.feed.AbsorptionFeed.endSelectedParentNode(AbsorptionFeed.java:81)
        at com.saxonica.ee.stream.watch.Trigger.endSelectedParentNode(Trigger.java:98)
        at com.saxonica.ee.stream.watch.WatchManager.endElement(WatchManager.java:497)
        at net.sf.saxon.event.StartTagBuffer.endElement(StartTagBuffer.java:308)
        at com.saxonica.ee.stream.ContentDetector.endElement(ContentDetector.java:56)
        at net.sf.saxon.event.Stripper.endElement(Stripper.java:169)
        at net.sf.saxon.event.ReceivingContentHandler.endElement(ReceivingContentHandler.java:528)
        at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.endElement(AbstractSAXParser.java:609)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanEndElement(XMLDocumentFragmentScan
nerImpl.java:1782)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocument
FragmentScannerImpl.java:2967)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:602)
        at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:112)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScanne
rImpl.java:505)
        at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:842)
        at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:771)
        at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
        at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213)
        at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:643)
        at net.sf.saxon.event.Sender.sendSAXSource(Sender.java:435)
        at net.sf.saxon.event.Sender.send(Sender.java:167)
        at net.sf.saxon.trans.XsltController.applyStreamingTemplates(XsltController.java:1050)
        at net.sf.saxon.s9api.AbstractXsltTransformer.applyTemplatesToSource(AbstractXsltTransformer.java:339)
        at net.sf.saxon.s9api.Xslt30Transformer.applyTemplates(Xslt30Transformer.java:311)
        at net.sf.saxon.Transform.processFile(Transform.java:1283)
        at net.sf.saxon.Transform.doTransform(Transform.java:815)
        at net.sf.saxon.Transform.main(Transform.java:80)
Caused by: java.lang.UnsupportedOperationException: last() cannot be used when streaming
        at net.sf.saxon.tree.iter.ManualIterator.getLength(ManualIterator.java:114)
        at net.sf.saxon.expr.XPathContextMinor.getLast(XPathContextMinor.java:237)
        at net.sf.saxon.functions.PositionAndLast$Last.evaluateItem(PositionAndLast.java:150)
        at net.sf.saxon.functions.PositionAndLast.call(PositionAndLast.java:126)
        at net.sf.saxon.functions.PositionAndLast$Last.call(PositionAndLast.java:148)
        at net.sf.saxon.expr.FunctionCall.iterate(FunctionCall.java:532)
        at net.sf.saxon.expr.Expression.evaluateItem(Expression.java:846)
        at net.sf.saxon.expr.CompareToIntegerConstant.effectiveBooleanValue(CompareToIntegerConstant.java:178)
        at net.sf.saxon.expr.instruct.Choose.choose(Choose.java:918)
        at net.sf.saxon.expr.instruct.Choose.evaluateItem(Choose.java:946)
        at net.sf.saxon.functions.ScalarSystemFunction$1.evaluateItem(ScalarSystemFunction.java:80)
        at net.sf.saxon.functions.ScalarSystemFunction$1.evaluateItem(ScalarSystemFunction.java:76)
        at net.sf.saxon.functions.Concat$1.evaluateAsString(Concat.java:92)
        at net.sf.saxon.functions.Concat$1.evaluateItem(Concat.java:102)
        at net.sf.saxon.expr.instruct.ComputedElement.getElementName(ComputedElement.java:289)
        at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:316)
        at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:299)
        at net.sf.saxon.expr.instruct.TemplateRule.applyLeavingTail(TemplateRule.java:352)
        ... 31 more
Fatal error during transformation: java.lang.RuntimeException: Internal error evaluating template rule  at line 22 in mo
dule file:/C:/SomePath/SomeDir/./sheet3.xsl

The code uses last(), however, in a template of a mode where no streaming is used:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    version="3.0">
    
    <xsl:strip-space elements="*"/>
    <xsl:output indent="yes"/>
    
    <xsl:mode on-no-match="shallow-copy" streamable="yes"/>
    
    <xsl:template match="Member">
        <xsl:copy>
            <xsl:for-each-group select="*" group-adjacent="node-name()">
                <xsl:apply-templates select="current-group()!copy-of()" mode="add-index"/>
            </xsl:for-each-group>
        </xsl:copy>
    </xsl:template>
    
    <xsl:mode name="add-index" on-no-match="shallow-copy"/>
    
    <xsl:template match="*[not(parent::*)]" mode="add-index">
        <xsl:element name="{node-name()}{if (last() gt 1) then '_' || position() else ()}">
            <xsl:apply-templates mode="#current"/>
        </xsl:element>
    </xsl:template>
    
</xsl:stylesheet>

The input sample (taken from a StackOverflow post) is

<?xml version="1.0" encoding="UTF-8"?> 
<Members>
    <Member>
        <Name>
            <fname>Fred</fname>
            <id>1234</id>
        </Name>
        <Locations>
            <name>Chicago</name>
            <days>3</days>
            <hours>24</hours>
        </Locations>
        <Locations>
            <name>Chicago</name>
            <days>3</days>
            <hours>24</hours>
        </Locations>
        <Payments>
            <amount>1000</amount>
            <currency>USD</currency>
        </Payments>
        <Payments>
            <amount>1000</amount>
            <currency>USD</currency>
        </Payments>
    </Member>
    <Member>
        <Name>
            <fname>Jack</fname>
            <id>4567</id>
        </Name>
        <Locations>
            <name>New York</name>
            <days>5</days>
            <hours>30</hours>
        </Locations>
        <Locations>
            <name>Chicago</name>
            <days>3</days>
            <hours>24</hours>
        </Locations>
        <Payments>
            <amount>1500</amount>
            <currency>USD</currency>
        </Payments>
        <Payments>
            <amount>1800</amount>
            <currency>USD</currency>
        </Payments>
    </Member>
</Members>

    (1-1/1)

    Please register to reply