gpt4 book ai didi

java - 内存不足错误: Java heap space using XSLT transform

转载 作者:行者123 更新时间:2023-12-02 02:33:19 25 4
gpt4 key购买 nike

我想使用 XSLT 转换 XML 文件。我做了:

TransformerFactory factory = TransformerFactory.newInstance();
InputStream is =
this.getClass().getResourceAsStream(getPathToXSLTFile());
Source xslt = new StreamSource(is);
Transformer transformer = factory.newTransformer(xslt);
Source text = new StreamSource(new File(getInputFileName()));
transformer.transform(text, new StreamResult(new File(getOutputFileName())));

哪个输入文件有大约 10000000 行,我有错误:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at com.sun.org.apache.xml.internal.utils.FastStringBuffer.append(FastStringBuffer.java:682)
at com.sun.org.apache.xml.internal.dtm.ref.sax2dtm.SAX2DTM.characters(SAX2DTM.java:2111)
at com.sun.org.apache.xalan.internal.xsltc.dom.SAXImpl.characters(SAXImpl.java:863)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.characters(AbstractSAXParser.java:546)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:455)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:841)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:770)
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.xalan.internal.xsltc.dom.XSLTCDTMManager.getDTM(XSLTCDTMManager.java:421)
at com.sun.org.apache.xalan.internal.xsltc.dom.XSLTCDTMManager.getDTM(XSLTCDTMManager.java:215)
at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.getDOM(TransformerImpl.java:556)
at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:739)
at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:351)
at ru.magnit.task.utils.AbstractXmlUtil.transformXML(AbstractXmlUtil.java:66)
at ru.magnit.task.EntryPoint.main(EntryPoint.java:72)

在这一行中:

 transformer.transform(text, new StreamResult(new File(getOutputFileName())));

这样做的原因是什么?可以在没有堆大小的情况下以某种方式对其进行优化吗?

更新:我的 XSLT 文件:

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

<xsl:output method="xml" indent="yes"/>

<xsl:template match="entries">
<entries>
<xsl:apply-templates/>
</entries>
</xsl:template>

<xsl:template match="entry">
<entry>
<xsl:attribute name="field">
<xsl:apply-templates select="*"/>
</xsl:attribute>
</entry>
</xsl:template>

最佳答案

一般来说,XSLT 1.0 和 2.0 使用的数据模型将完整的 XML 输入拉入树模型以允许完整的 XPath 导航,从而导致内存使用量随着输入文档的大小而增加。

因此,除非您增加堆空间,否则如果您当前的文档大小导致内存不足,您无能为力,至少一般而言,可能存在特定于 XSLT 处理器和一些特定于 XSLT 的优化,具体取决于您的具体 XSLT 代码,但您无法避免处理器首先提取完整的文档。我们需要查看您的 XSLT 来尝试判断它是否可以优化。分析样式表可以帮助识别需要优化的区域,我不确定 Xalan 是否支持这一点。我不确定该堆栈跟踪是否仅仅意味着 Xalan 在为大型输入构建 DTM(其树模型)时已经耗尽内存,在这种情况下,显然优化 XSLT 代码没有帮助,因为它甚至没有被执行.

您可以尝试的一种 Java 特定方法是使用 https://docs.oracle.com/javase/8/docs/api/javax/xml/transform/sax/SAXTransformerFactory.html相反,从样式表创建 SAX 过滤器并将其与默认 Transformer 链接以序列化过滤器的结果,我想我曾经尝试过,发现它比使用 Transformer 的传统方法消耗的内存更少。

XSLT 3.0 尝试使用新的流方法 ( https://www.w3.org/TR/xslt-30/#streaming-concepts ) 来解决内存问题,但是到目前为止,只有一种商业产品 Saxon 9 EE 的实现。一般来说,样式表不一定是可流式的,相反,您必须重写它以使其可流式传输(如果可能的话,例如,通过流式传输不可能对输入节点进行排序)。

例如,您发布的样式表转换为 XSLT 3.0 以使用流式传输(无需重写,只需将默认模式设置为可流式传输)

<?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"
xmlns:math="http://www.w3.org/2005/xpath-functions/math"
exclude-result-prefixes="xs math"
version="3.0">

<xsl:mode streamable="yes"/>

<xsl:output method="xml" indent="yes"/>

<xsl:template match="entries">
<entries>
<xsl:apply-templates/>
</entries>
</xsl:template>

<xsl:template match="entry">
<entry>
<xsl:attribute name="field">
<xsl:apply-templates select="*"/>
</xsl:attribute>
</entry>
</xsl:template>

</xsl:stylesheet>

Saxon 9.8 EE 和 Exselt 测试版将其评估为可流式传输。

关于java - 内存不足错误: Java heap space using XSLT transform,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46748327/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com