技術のメモ帳

気が向いたときに書いてます

[GAS]HTML/XMLをパースする

Google Apps Scriptは、サーバサイドJavaScriptのため、DomparserクラスやjQueryを用いたDOMの操作ができません

そのため、HTML/XMLをパースする際は、XMLServiceクラスを利用します。

XMLServiceの使い方

XML Service Service  |  Apps Script  |  Google Developers

ドキュメントを見た方が早いかもしれませんが、パースする手順は以下の通りです。

  1. UrlFetchApp.fetch()メソッドで対象のリソースを取得
  2. HTTPResponseクラスのgetContentText()からリソースを文字列に変換
  3. XMLService.parse()メソッドで、対象のXMLをパース
function parseXml() {
  var xml = UrlFetchApp.fetch('http://sample.com/example.xml').getContentText();
      doc = XmlService.parse(xml);
}

XMLServiceという名前のクラスですが、well-formedであれば、HTMLでも利用可能です。

難点としては、最上位の階層から常にgetChild()メソッド等で辿る必要があるため、若干扱いが面倒ではあります。

DOMツリーのように扱う

上記の記事でDOMツリーのように扱うアプローチがあり、非常に便利でした。

具体的には、次のような関数を追加します(一部修正しています)。

function getElementById(element, idToFind) {
  var descendants = element.getDescendants();
  for (var i in descendants) {
    var elem = descendants[i].asElement();
    if ( elem != null) {
      var id = elem.getAttribute('id');
      if ( id != null && id.getValue() == idToFind) return elem;
    }
  }
}

function getElementsByClassName(element, classToFind) {
  var data = [], descendants = element.getDescendants();
  descendants.push(element);
  for (var i in descendants) {
    var elem = descendants[i].asElement();
    if (elem != null) {
      var classes = elem.getAttribute('class');
      if (classes != null) {
        classes = classes.getValue();
        if (classes == classToFind) {
          data.push(elem);
        } else {
          classes = classes.split(' ');
          for (var j in classes) {
            if (classes[j] == classToFind) {
              data.push(elem);
              break;
            }
          }
        }
      }
    }
  }
  return data;
}

function getElementsByTagName(element, tagName) {
  var data = [], descendants = element.getDescendants();
  for(var i in descendants) {
    var elem = descendants[i].asElement();
    if ( elem != null && elem.getName() == tagName) data.push(elem);
  }
  return data;
}

これらの関数を追加すると、クライアントサイドのJavaScriptのように、DOMツリーを探索することができるようになります。

var src = '<doc>'
        + '  <title id="doc-title">In the airport</title>'
        + '  <chapter class="chapter">'
        + '    <paragraph class="paragraph">Why did you come to Japan?</paragraph>'
        + '  </chapter>'
        + '</doc>';

function parseXML() {
  var doc   = XmlService.parse(src),
      xml   = doc.getRootElement(),
      title = getElementById(xml, 'doc-title');
  Logger.log(title.getValue());
}