当前位置: 首页 > 知识库问答 >
问题:

未定义有效布尔值-XSLT

苏选
2023-03-14

在对XML文件应用转换时,我得到了这个错误(即,未定义有效的布尔值)。这里有一个奇怪的陷阱:

*我的应用程序从一个文件位置读取500到800个XML文件(XML文件大小范围从几KB到10MB),然后对每个文件进行转换。最初一切都很顺利,但在一些执行之后,它会在错误下面抛出:

productsfromloc_v3.xsl:
forg0006第651行错误:在xsl:call-template name=“assetstream”(文件://c://app/comp/nfs/services/transformer/productsfromloc_v3.xsl#378)处未定义有效布尔值
(文件://c://app/comp/nfs/services/transformer/productsfromloc_v3.xsl#53)

第651行是:xsl:if test=“fn:string-length(fn:copy-of($vstruct))!=0”

一旦该错误在转换时开始出现,则rest所有转换将导致相同的错误。

如果我选择那些错误的XML文件,然后单独处理,那么根本没有问题。似乎批量XML转换只会导致这个问题。

Java代码:

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(); }

导致错误的XSLT部分:

<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 &lt; 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>

共有1个答案

顾乐池
2023-03-14

作为实验,请关闭字节码生成。(featurekeys.generate_byte_code)

字节码生成是在构造执行一定次数后开始的,这与您的观察一致,即只有在运行一定次数的转换后才会出现失败,如果单独运行这些转换则不会出现失败。

我认为这个问题很有可能是由不正确的字节码生成引起的。如果事实证明是这样,我们显然希望您帮助我们找到实际的bug(而不是仅仅解决它):为此,尝试以较低的字节码生成阈值运行,以便它更快地发挥作用(featurekeys.theshold_for_hotspot_bytecode)。

 类似资料:
  • 我想基于自定义布尔值设置表单元素的有效性。考虑下面的密码字段: 如果重复的密码与原始密码匹配,我想标记第二个输入字段有效。类似的东西: 为此,我找不到任何角度指示。有什么想法吗?也许我可以为此制定自己的指令?不幸的是,我不是一个角度专家。。。应该是这样的: 谢谢

  • 到目前为止我们看到的类型都能表示很大范围的数据,整数多的是,而浮点数更多。相对而言,字符集的规模小的多。C++中还有一个类型表示的范围更小,即布尔类型,它只能表示true和false两个值。 虽然没提到过该类型,但我们前面几章中实际已经使用过布尔值了。if语句和while语句中的条件就是布尔表达式。比较操作符的结果也是布尔值。例如: if (x == 5) { // 进行某些处理 } ==操

  • 原文: http://exploringjs.com/impatient-js/ch_booleans.html 基本类型 _ 布尔 _ 包含两个值 - false和true: > typeof false 'boolean' > typeof true 'boolean' 14.1。转换为布尔值 这三种方法可以将任意值x转换为布尔值。 Boolean(x) 最具描述性;推荐的。 x ?

  • 问题内容: 在Java虚拟机规范说有布尔有限的支持原始类型。 没有Java虚拟机指令专门用于布尔值的操作。相反,将对布尔值进行操作的Java编程语言中的表达式编译为使用Java虚拟机int数据类型的值。 以上暗示(尽管我可能会误解了)在对布尔值进行操作时使用了int数据类型,但这是一个32位内存构造。假设布尔值仅表示1位信息: 为什么不将字节(或简称)类型用作布尔值而不是int的代理? 对于任何给

  • 问题内容: 为什么不像天真的预期那样起作用? (输出为) 问题答案: 为了与Python 2-3兼容,只需将其添加到示例中: 或将Foo的原始定义扩展为包括: 当然,您也可以反过来定义它们,方法名称在哪里,然后将其分配给,但是我认为该名称只是Python根据其与对象的等价性将对象解释为真或假的原始C- ishness的遗产。零。只需添加上面的语句,您的代码即可在Python 2.x上运行,并且在升

  • 问题内容: 我有一个MPClient和MultiplayerMatch类。MultiplayerMatch在其构造函数中创建一个MPClient可运行线程。 为了避免数据溢出,我在MultiplayerMatch中有一个名为“ moved”的布尔值,当播放器移动时,它会变为true。 在updateMatch方法中,如果有任何播放器移动,则“ moved”变为true,这允许MPClient输入i