【问题标题】:Problem with reading large XML file into Javascript将大型 XML 文件读入 Javascript 的问题
【发布时间】:2021-10-18 10:50:46
【问题描述】:

我创建了一个网站,您可以在其中导入 XML 文件,然后将其读出。它适用于大多数文件,但我尝试使用 730MB 的 XML 文件,但它不再工作了。我似乎没有在控制台上收到任何错误,但如果我使用此代码,

numberOfReports = xmlDoc.getElementsByTagName("DailyReport").length;

我总是得到 0,即使它应该远不止这些,因为 XML 文件肯定包含多个 <DailyReport> 元素。我导入和解析文件的函数如下所示:

// Function to import and serialize the XML file
function import_XML() {
    var input = document.createElement('input');
    input.type = 'file';

    input.onchange = e => {

        // getting a hold of the file reference
        file = e.target.files[0];

        // setting up the reader
        var reader = new FileReader();
        reader.readAsText(file, 'UTF-8');

        // Tell the reader what to do when it's done reading
        reader.onload = readerEvent => {
            content = readerEvent.target.result;
            const parser = new DOMParser();
            xmlDoc = parser.parseFromString(content, "application/xml");
            console.log(xmlDoc.documentElement.nodeName == "parsererror" ? "Error while parsing XML File" : xmlDoc.documentElement.nodeName);
            console.log("content: " + content);

            // Number of reports in the XML file
            numberOfReports = xmlDoc.getElementsByTagName("DailyReport").length;
            console.log("number of daily reports: " + numberOfReports);
            updateTable();

        }
    }
    input.click();
}

我在控制台中从content = readerEvent.target.result;得到的内容也是空的:

我不确定是不是因为文件太大,但是 XML 文件应该没有任何畸形。谁能帮我解决这个问题?非常感谢任何帮助!

【问题讨论】:

  • 在寻求帮助时,请花时间缩进并格式化您的代码,使其可读。仅阅读部分缩进的代码真的很难。 (我已经通过一个基本的格式化程序为你运行了代码。)
  • 从您的控制台屏幕截图中,content 看起来是一个空字符串。这与nodeName 显示为"html" 是一致的(当我使用(new DOMParser().parseFromString("", "application/xml")).documentElement.nodeName 时我明白了)。所以问题是:为什么字符串是空的? (另外:你在哪里声明content?)
  • 我将文件顶部的内容声明为var content;,以便我可以在其他函数中访问它。至于为什么字符串是空的,我真的不知道。对于工作 XML 文件,内容将整个 XML 作为字符串返回。

标签: javascript html xml xml-parsing


【解决方案1】:

我怀疑您超出了浏览器 JavaScript 引擎的最大字符串长度。不同的引擎有不同的限制。 MDN says Firefox 的限制大约是 1GB(虽然我只是尝试了一个实验,它更像是 800MB)。 Brave(类似 Chrome)中的一个快速实验表明最大约为 512MB:

let size = 0;
const chunk = "".padStart(4096, " ");
const max = 800 * 1024 * 1024;
try {
    let str = "";
    while (str.length < max) {
        size = str.length;
        str += chunk;
    }
    console.log(`worked! size = ${size / 1024 / 1024}`);
} catch {
    console.log(`ERROR, size = ${size / 1024 / 1024}`);
}

Node.js 中的相同实验(它使用与基于 Chromium 的浏览器相同的 JavaScript 引擎,V8)产生相同的结果,这表明它是 V8 中的限制。

不幸的是,DOMParser 只接受字符串,而不接受(比如说)blob。我认为您可能无法在基于 V8 的浏览器上处理这么大的文件。

我怀疑DOMParser 有一天会得到一个允许它读取streams 的方法,但现在这对你没有帮助。我能想到的唯一解决方案是找到一个用 JavaScript 编写的 XML 解析器,它要么支持流,要么您可以适应使用流。 npm 包中有几个 XML 解析器,可能有一个可以使用 blob,或者一个 ReadableStream,或者一个支持 Node.js 流的,你可以适应 ReadableStream(以及浏览器的版本XML 文档,而不是他们在 Node.js 上使用的任何东西)。

【讨论】:

  • 感谢您的回答和代码 sn-p。你认为有什么办法可以解决这个问题吗?也许以不同的方式解析 XML 文件或您不必使用字符串的任何方式?
  • @Mimi - 恐怕我不知道具体的方式。我已添加到答案的末尾。
猜你喜欢
  • 2010-09-08
  • 1970-01-01
  • 2013-09-13
  • 2023-04-05
  • 2015-07-07
  • 2019-07-14
  • 1970-01-01
  • 1970-01-01
  • 2020-08-11
相关资源
最近更新 更多