Mule 3.4.2 XSLT Transformer throws Cannot write mo

2019-09-17 09:48发布

问题:

I have XML coming to a mule flow. I need to break this xml into 3 different xml and write to 3 files. This is how I call XSLT Transformer in mule flow.

    <xm:xslt-transformer xsl-file="xsl/xml-to-file.xsl">
        <xm:context-property key="A_loc" value="${location.a}" />
        <xm:context-property key="B_loc" value="${location.b}" />
        <xm:context-property key="C_loc" value="${location.c}" />
    </xm:xslt-transformer>

And this is how the xsl is defined:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="text" />

<xsl:param name="A_loc" />
<xsl:param name="B_loc" />
<xsl:param name="C_loc" />

<xsl:template match="/">
    <xsl:apply-templates select="//table[@name='A_DATA']" />
    <xsl:apply-templates select="//table[@name='B_DATA']" />
    <xsl:apply-templates select="//table[@name='C_DATA']" />
</xsl:template>

<xsl:template match="table[@name='A_DATA']">
    <xsl:result-document href="{$A_loc}" >
        <xsl:for-each select="row">
            <xsl:for-each select="field">
                .... some logic
            </xsl:for-each>
            <xsl:text>&#13;</xsl:text>
        </xsl:for-each>
    </xsl:result-document>
</xsl:template>

<xsl:template match="table[@name='B_DATA']">
    <xsl:result-document href="{$B_loc}">
        <xsl:for-each select="row">
            <xsl:for-each select="field">
                ... some logic
            </xsl:for-each>
            <xsl:text>&#13;</xsl:text>
        </xsl:for-each>
    </xsl:result-document>
</xsl:template>

<xsl:template match="table[@name='C_DATA']">
    <xsl:result-document href="{$C_loc}">
        <xsl:for-each select="row">
            <xsl:for-each select="field">
                ... some logic
            </xsl:for-each>
            <xsl:text>&#13;</xsl:text>
        </xsl:for-each>
    </xsl:result-document>
</xsl:template>

This process is scheduled to run at a particular frequency. The very first time after starting server, it runs fine but all subsequent runs fail with this message

org.mule.exception.DefaultMessagingExceptionStrategy - ******************************************************************************** Message : Cannot write more than one result document to the same URI, or write to a URI that has been read: file:/C:/data/local/A/Axyz.txt (net.sf.saxon.trans.DynamicError) Code : MULE_ERROR-64999 -------------------------------------------------------------------------------- Exception stack is: 1. Cannot write more than one result document to the same URI, or write to a URI that has been read: file:/C:/data/local/A/Axyz.txt(net.sf.saxon.trans.DynamicError)
net.sf.saxon.instruct.ResultDocument:300 (null) 2. Cannot write more than one result document to the same URI, or write to a URI that has been read: file:/C:/data/local/A/Axyz.txt (net.sf.saxon.trans.DynamicError) (org.mule.api.transformer.TransformerException)
org.mule.module.xml.transformer.XsltTransformer:188


I checked mule is using saxon 8.9.0.4-osgi, saxon-dom 8.9.0.4-osgi and saxon-xqj 8.9.0.4

回答1:

xsl:result-document isn't designed to append nor to overwrite files. If you need to overwrite you'll have to use a component previous to your xslt to delete or backup your file prior to recreation.

Another possibility I would recommend is to abuse both the source code of the xslt transformer and Saxon's OutputURIResolver but I would really trust this one.



回答2:

It was a bug in Mule 3.4.2 and is addressed here.

https://www.mulesoft.org/jira/browse/MULE-5382

Mule support provided a patch for this . Basically, they reset transformer after clearing the parameters in XsltTransformer file.