将大型 XML 文件读入 Javascript 时出现问题

Problem with reading large XML file into Javascript

我创建了一个网站,您可以在其中导入 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文件应该不会有什么乱码。谁能帮我解决这个问题?非常感谢任何帮助!

我怀疑您超过了浏览器 JavaScript 引擎的最大字符串长度。不同的引擎有不同的限制。 MDN says Firefox 的限制大约是 1GB(虽然我刚刚尝试了一个实验,它更像是 800MB)。在 Brave 中进行的快速实验(Chrome-like)建议最大约 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 的浏览器 V8 相同的 JavaScript 引擎)产生相同的结果,表明这是 V8 中的限制。

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

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