Help us understand the problem. What is going on with this article?

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

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

tom_konda
主にPHPを書いていますが、JavaScriptの方が好きです。 Openstreetmapのマッパーもやってます。
dgcircus
オープンソースCMS「Drupal」の導入・カスタマイズ開発、スマートフォンアプリ開発を行うIT企業
https://www.dgcircus.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした