I am getting this error (i.e. Effective boolean value not defined) while applying transformation on XML files. There is a strange catch here:
*My application reads 500 to 800 XML files (XML file size range from few KB to 10MB) from a file location, and then does transformation on each of them. Initially everything goes smooth, but after some executions it throws below error:
Error on line 651 of productsFromLOC_v3.xsl:
FORG0006: Effective boolean value is not defined
at xsl:call-template name="AssetStream"
(file:/C:/app/comp/nfs/services/transformer/productsFromLOC_v3.xsl#378)
at xsl:call-template name="Products"
(file:/C:/app/comp/nfs/services/transformer/productsFromLOC_v3.xsl#53)
Line no 651 is: xsl:if test="fn:string-length( fn:copy-of($vStruct)) != 0"
Once this error starts appearing while a transformation, rest all transformation then results in same error.
If I pick those error-ed XML files, and process then individually, then there is no issue at all. Seems as if bulk XML transformation causes this problem only.
Can somebody help me in this scenario?
Saxon EE version - 9.8.0.7J, and XSLT version - 3.0
Java code :
private byte[] transformFromSource(String urlParams, String xslFullPath, final String uriXSLT,
final String outputXSLTFilePath, String transformParams, final Object xmlSource,
final String outputEncoding)
throws SaxonApiException, MalformedURLException, SystemException, UnsupportedEncodingException {
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
List<XsltExecutable> xsltExecutables = xsltTemplateManager.getTemplates(windowsOS ? xslFullPath.split("\\\\")[xslFullPath.split("\\\\").length - 1].trim() : xslFullPath.trim());
Processor processor = null;
XdmNode xdmNode = null;
XdmDestination xdmDestination1 = new XdmDestination();
XdmDestination xdmDestination2 = new XdmDestination();
for (XsltExecutable xsltExecutable : xsltExecutables) {
int i = 0;
final Xslt30Transformer transformer = xsltExecutable.load30();
final Map<QName, XdmValue> params = new HashMap<QName, XdmValue>();
if (StringUtils.isNotBlank(uriXSLT)) {
params.put(new QName("xslt.location.uriXSLTPath"), new XdmAtomicValue(uriXSLT));
}
if (StringUtils.isNotBlank(outputXSLTFilePath)) {
params.put(new QName("xslt.location.outputXSLTPath"), new XdmAtomicValue(outputXSLTFilePath));
}
if (StringUtils.isNotBlank(transformParams)) {
params.put(new QName("xslt.transform.params"), new XdmAtomicValue(transformParams));
}
if (StringUtils.isNotBlank(urlParams)) {
params.put(new QName("http.query.params"), new XdmAtomicValue(urlParams));
}
transformer.setStylesheetParameters(params);
if (xsltExecutables.size() == 1) {
processor = xsltExecutable.getProcessor();
if (xmlSource instanceof File) {
if (((File) xmlSource).isFile()) {
String inFile = "<file>" + ((File) xmlSource).getAbsolutePath() + "</file>";
xdmNode = processor.newDocumentBuilder().build(new StreamSource(new ByteArrayInputStream(inFile.getBytes(outputEncoding))));
}
} else {
xdmNode = processor.newDocumentBuilder().build((StreamSource) xmlSource);
}
final Serializer serializer = processor.newSerializer(outputStream);
/* serializer.setOutputProperty(Serializer.Property.METHOD, "xml"); */
serializer.setOutputProperty(Serializer.Property.INDENT, "yes");
serializer.setOutputProperty(Serializer.Property.ENCODING, outputEncoding);
transformer.applyTemplates(xdmNode, serializer);
} else if (xsltExecutables.size() > 1 && i == 0) {
processor = xsltExecutable.getProcessor();
if (xmlSource instanceof File) {
xdmNode = processor.newDocumentBuilder().build((File) xmlSource);
} else {
xdmNode = processor.newDocumentBuilder().build((StreamSource) xmlSource);
}
transformer.applyTemplates(xdmNode, xdmDestination1);
} else if (xsltExecutables.size() > 1 && i == xsltExecutables.size()) {
final Serializer serializer = processor.newSerializer(outputStream);
serializer.setOutputProperty(Serializer.Property.INDENT, "yes");
serializer.setOutputProperty(Serializer.Property.ENCODING, outputEncoding);
transformer.applyTemplates(xdmNode, serializer);
transformer.applyTemplates(xdmDestination2.getXdmNode(), serializer);
} else if (xsltExecutables.size() > 1 && i > 0) {
transformer.applyTemplates(xdmDestination1.getXdmNode(), xdmDestination2);
xdmDestination1 = xdmDestination2;
}
}
processor = null;
xdmNode = null;
xsltExecutables = null;
return outputStream.toByteArray(); }
Section of XSLT which results in error:
<xsl:iterate select="$STEP/STEP-ProductInformation/Assets/Asset[@UserTypeID='PDF' or @UserTypeID='PNG']">
<xsl:param name="vCount" select="1" as="xs:integer"/>
<xsl:param name="vFileCount" select="1" as="xs:integer"/>
<xsl:param name="vStruct" select="'' " as="xs:string"/>
<xsl:on-completion>
<xsl:variable name="vFileName" select="concat($outputXSLTFilePath,'/Asset-',$vTimestamp,'-',$vFileCount,$vJMSID,'.xml')"/>
<xsl:variable name="vResult">
<map xmlns="http://www.w3.org/2005/xpath-functions">
<array key="assets">
<xsl:copy-of select="$vStruct"/>
</array>
<string key="locale">
<xsl:value-of select="$vContextID"/>
</string>
<string key="exportTime">
<xsl:value-of select="$vExportTime"/>
</string>
</map>
</xsl:variable>
<xsl:if test="fn:string-length( fn:copy-of($vStruct)) ne 0">
<Payload>
<ControlData>
<FeedType>Assets</FeedType>
<FullImport>
<xsl:value-of select="$fullUpload"/>
</FullImport>
<Resequencing>true</Resequencing>
<JMSXGroupID>
<xsl:value-of select="$vJMSID"/>
</JMSXGroupID>
<JMSXGroupSeq>
<xsl:value-of select="$vFileCount"/>
</JMSXGroupSeq>
<GroupSize>
<xsl:value-of select="$vTotalMessages"/>
</GroupSize>
<OutboundQueueName>feeds/out/1.0/products</OutboundQueueName>
</ControlData>
<Message id="{$vFileCount}">
<xsl:value-of select="odfn:JsonBS(xml-to-json($vResult,map{ 'indent':true() }))"/>
</Message>
</Payload>
</xsl:if>
</xsl:on-completion>
<xsl:variable name="vX">
<map xmlns="http://www.w3.org/2005/xpath-functions">
<string key="id">
<xsl:value-of select="@ID"/>
</string>
<string key="typeId">
<xsl:value-of select="@UserTypeID"/>
</string>
<string key="filename">
<xsl:value-of select="./Values/Value[@AttributeID='asset.filename']"/>
</string>
</map>
</xsl:variable>
<xsl:variable name="vXS">
<xsl:copy-of select="$vStruct"/>
<xsl:copy-of select="$vX"/>
</xsl:variable>
<xsl:choose>
<xsl:when test="$vCount < 50">
<xsl:next-iteration>
<xsl:with-param name="vCount" select="$vCount+1"/>
<xsl:with-param name="vFileCount" select="$vFileCount"/>
<xsl:with-param name="vStruct">
<xsl:copy-of select="$vXS"/>
</xsl:with-param>
</xsl:next-iteration>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="vFileName" select="concat($outputXSLTFilePath,'/Asset-',$vTimestamp,'-',$vFileCount,$vJMSID,'.xml')"/>
<xsl:variable name="vResult">
<map xmlns="http://www.w3.org/2005/xpath-functions">
<array key="assets">
<xsl:copy-of select="$vXS"/>
</array>
<string key="locale">
<xsl:value-of select="$vContextID"/>
</string>
<string key="exportTime">
<xsl:value-of select="$vExportTime"/>
</string>
</map>
</xsl:variable>
<Payload>
<ControlData>
<FeedType>Assets</FeedType>
<FullImport>
<xsl:value-of select="$fullUpload"/>
</FullImport>
<Resequencing>true</Resequencing>
<JMSXGroupID>
<xsl:value-of select="$vJMSID"/>
</JMSXGroupID>
<JMSXGroupSeq>
<xsl:value-of select="$vFileCount"/>
</JMSXGroupSeq>
<GroupSize>
<xsl:value-of select="$vTotalMessages"/>
</GroupSize>
<OutboundQueueName>feeds/out/1.0/products</OutboundQueueName>
</ControlData>
<Message id="{$vFileCount}">
<xsl:value-of select="odfn:JsonBS(xml-to-json($vResult,map{ 'indent':true() }))"/>
</Message>
</Payload>
<xsl:next-iteration>
<xsl:with-param name="vCount" select="1"/>
<xsl:with-param name="vFileCount" select="$vFileCount+1"/>
<xsl:with-param name="vStruct" select="''"/>
<!-- blank -->
</xsl:next-iteration>
</xsl:otherwise>
</xsl:choose>
uri-collection
orcollection
, then show that exactly, if you have Java or C# plumbing code to run the stylesheet against all the files, then show that code. – Martin Honnenxsl:if test="fn:string-length( fn:copy-of($vStruct)) != 0"
from the question nowxsl:if test="fn:string-length( fn:copy-of($vStruct)) ne 0"
in the code snippet? I can't explain the error but the use ofxs:string
in the initial param declarationxsl:param name="vStruct" select="'' " as="xs:string"
while then passing onmap
elements seems to suggest you rather wantxsl:param name="vStruct" as="element(fn:map)*" select="()" xmlns:fn="http://www.w3.org/2005/xpath-functions"
and then you want to checkif (not($vStruct))
orif (exists($vStruct))
. – Martin Honnen