クライアントサイドで JavaScriptでFileReaderを使用してファイルの処理をする際、稀にXML文書を処理する必要に迫られることがあります。その時必要な実装の例と注意点を記載します。
XMLHttpRequestとFileReaderの違い
XMLHttpRequestの場合、ブラウザがデフォルトでDOMを構築するため、そのDOMを元に文書の処理をできますが、FileReaderからXML文書を処理する場合はファイルをテキストとして処理するか、バイナリとして処理するかのどちらかしか無いため、プログラム側で明示的にDOMを構築させる必要があります。
#実装例
デモ
下記のようなXMLファイルをJavaScriptで読み込む場合、
<doc>
<title id="doc-title">テストXML文書</title>
<chapter class="chapter first-chapter" id="chapter-1">
<paragraph class="paragraph first-paragraph last-paragraph">
</paragraph>
</chapter>
<chapter class="chapter" id="chapter-2">
<paragraph class="paragraph first-paragraph">
</paragraph>
<paragraph class="paragraph">
</paragraph>
<paragraph class="paragraph last-paragraph">
</paragraph>
</chapter>
<chapter class="chapter last-chapter" id="chapter-3">
<paragraph class="paragraph first-paragraph">
</paragraph>
<paragraph class="paragraph last-paragraph">
</paragraph>
</chapter>
</doc>
XMLのDOMは DOMParser.parseFromString を使用することでDOMを構築できます。
// files変数は File オブジェクト
var file = files[0];
var reader = new FileReader();
reader.addEventListener('load', parseXML, false);
reader.readAsText(file);
function parseXML(e){
'use strict';
var xml = e.target.result;
// XMLのDOMをパースする
var parser = new DOMParser();
var dom = parser.parseFromString(xml, 'text/xml');
}
後は、dom変数に対して、 document.querySelectorAll メソッドや document.getElementsByTagName メソッドを使用することで、目的となる要素を取得することが可能になります。
// files変数は File オブジェクト
var file = files[0];
var reader = new FileReader();
reader.addEventListener('load', parseXML, false);
reader.readAsText(file);
function parseXML(e){
'use strict';
var xml = e.target.result;
// XMLのDOMをパースする
var parser = new DOMParser();
var dom = parser.parseFromString(xml, 'text/xml');
var title = dom.getElementById('doc-title').textContent;
console.log(title);
var paragraphs = dom.getElementsByTagName('paragraph').length;
console.log(paragraphs);
var result = dom.querySelectorAll('.chapter > .first-paragraph').length;
console.log(result);
}
注意点
Webworker上では、DOMに関するメソッドを使用できないため、ファイルを Webworkerで処理することは不可能です。そのため、Webworkerを使ったファイルの処理高速化の恩恵を受けることはできません。