有一个处理 xml 文件的客户端应用程序(不是 node.js!)。用户在页面上加载它们,然后需要在浏览器中对其进行解析。非常简化的代码是这样的:
function openFile(event) {
let input = event.target;
let reader = new FileReader();
reader.onload = function () {
parse(reader.result);
};
reader.onerror = function () {
console.log(reader.error);
};
reader.readAsText(input.files[0]);
}
function parse(text) {
let parser = new DOMParser();
let xml = parser.parseFromString(text, "text/xml");
console.log(xml.xmlEncoding); //ок, но что дальше?
for (let row of xml.getElementsByTagName("row")) {
console.log(row.getAttribute("name"), row.firstChild.nodeValue);
}
}
<input type="file" id="file" accept=".xml" onchange="openFile(event)">
XML 文件的内容无关紧要,例如:
<?xml version="1.0" encoding="utf-8"?>
<data>
<row name='имя'>значение</row>
</data>
如果文件是编码的UTF-8,那么一切都很好。但它可以是,例如,编码windows-1251的,然后结构被保留,但内部имя和значение将是问号。
如果我使用显式编码调用 read ,那么一切都会正常工作:
reader.readAsText(input.files[0], 'windows-1251');
但问题是我不知道它最初是什么。怎样成为?
不幸的是,我不知道这里有什么传统或经过验证的算法,我只能提出几个选项。
向指定编码的表单添加一个附加字段。
使用 . 将文件作为缓冲区读取
FileReader.readAsArrayBuffer()。将其传递给解析函数。在那里,首先尝试使用TextDecoder. 如果可以读取编码但不匹配,请以相同的方式重新编码,但使用指定的编码。但是,如果编码是 UTF-16,这可能不起作用。但是,也许,它DOMParser会给出一个错误,可以捕获它并使用多字节编码重试。寻找可以从缓冲区的一部分猜测编码的库(例如,Google 上的“npm guess encoding”)。