JavaScript
XML

クライアントサイドJavaScriptでXML文書のDOMをパースする

More than 3 years have passed since last update.

クライアントサイドで JavaScriptでFileReaderを使用してファイルの処理をする際、稀にXML文書を処理する必要に迫られることがあります。その時必要な実装の例と注意点を記載します。

XMLHttpRequestとFileReaderの違い

XMLHttpRequestの場合、ブラウザがデフォルトでDOMを構築するため、そのDOMを元に文書の処理をできますが、FileReaderからXML文書を処理する場合はファイルをテキストとして処理するか、バイナリとして処理するかのどちらかしか無いため、プログラム側で明示的にDOMを構築させる必要があります。

実装例

デモ

下記のようなXMLファイルをJavaScriptで読み込む場合、

test1.xml
<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を構築できます。

parse_xml.js
    // 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 メソッドを使用することで、目的となる要素を取得することが可能になります。

parse_xml2.js
    // 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を使ったファイルの処理高速化の恩恵を受けることはできません。