XMLデータ(RSS)が見づらい

先日、社内でこんな相談を受ける。

「Googleのマーチャントセンター用のフィードデータをXMLで取得しているが、そのままだと見づらいので表形式に出力できないですか?」

という相談。ExcelかGoogleスプレッドシートのマクロを使って出せないかなと考える。せっかくなのでスプレッドシートでGoogle Apps Scriptを久しぶりに組んでみようと思い実装してみることに。まずはXML情報取得までの前編。

Class XmlService

Google Apps ScriptにはXMLをコントロールするClass XmlService が準備されています。このClassを使用して処理を実装します。

XML情報の取得

まずはXML情報を取得するところまで実装。テストデータとしてこのブログのRSS情報を取得してみる。

function parseXml() {
  // フィードのURL設定
  var feedURL = "https://www.terakoya.work/feed/";

  // フィードを取得
  var response = UrlFetchApp.fetch(feedURL);

  // XMLをパース
  var xml = XmlService.parse(response.getContentText());

  // 各データの要素を取得
  var entries = xml.getRootElement().getChildren(“channel")[0].getChildren(“item");

  // 要素数を取得
  var length = entries.length;

  // 取得したデータをループさせる
  for(var i = 0; i < length; i++) {
    // 記事タイトル
    var title = entries[i].getChildText("title");

    // ログに出力
    Logger.log(title);
  }
}

処理のフローは以下の通り。

  1. 03行目 – feedURL変数にフィードのURLをセット
  2. 06行目 – Class UrlFetchAppparseメソッドでフィードを取得
  3. 09行目 – XmlServiceparseメソッドでXMLデータをパース
  4. 12行目 – XMLデータの記事情報(item要素)を変数に取得
  5. 15行目 – 記事数(item要素の数)を取得
  6. 18行目 – 取得した記事をループする。getChildTextで要素を指定(ここではtitle要素)して変数に保存。その値をログに出力

という流れ。とてもシンプル。実行するとログは以下のように出力されます。

title要素をログ出力

XML名前空間で定義されている要素

title要素と同様にcreator要素を取得しようとします。すると、nullが返ってきました。

creator要素の取得(null)

XMLのデータは、以下のようになっています。

<dc:creator><![CDATA[高見 和也]]></dc:creator>

「あ、名前空間で定義されている要素だ」と思い、「dc」の名前空間の定義をみてみる。XMLデータのヘッダー部分を見れば記述があります。

<?xml version="1.0" encoding="UTF-8"?>
	<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

5行目に名前空間dcの定義がされていますので、これを先程のコードに追記します。

function parseXml() {
  // フィードのURL設定
  var feedURL = "https://www.terakoya.work/feed/";

  // フィードを取得
  var response = UrlFetchApp.fetch(feedURL);

  // XMLをパース
  var xml = XmlService.parse(response.getContentText());

  // 名前空間
  var namespace = XmlService.getNamespace("dc", "http://purl.org/dc/elements/1.1/");

  // 各データの要素を取得
  var entries = xml.getRootElement().getChildren("channel")[0].getChildren("item");

  // 要素数を取得
  var length = entries.length;

  // 取得したデータをループさせる
  for(var i = 0; i < length; i++) {
    // 記事タイトル
    var title = entries[i].getChildText("title");

    // 投稿者
    var creator = entries[i].getChildText("creator", namespace);

    // ログに出力
    Logger.log(creator);
  }
}

ポイントは2点。まず12行目に追加した処理。getNamespaceメソッドで、引数で名前空間のプレフィックスと定義URIを渡して名前空間を取得します。

取得した名前空間を、名前空間定義要素を取得する際に第二引数として渡します(26行目)。これで取得できているはずなのでログを確認してみます。

creator要素の取得(成功)

とれた!\(^o^)/
これで項目取得は達成したので、後編で取得した情報をスプレッドシートに出力してみようと思います。