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);
}
}
処理のフローは以下の通り。
- 03行目 – feedURL変数にフィードのURLをセット
- 06行目 –
Class UrlFetchApp
のparse
メソッドでフィードを取得 - 09行目 –
XmlService
のparse
メソッドでXMLデータをパース - 12行目 – XMLデータの記事情報(item要素)を変数に取得
- 15行目 – 記事数(item要素の数)を取得
- 18行目 – 取得した記事をループする。
getChildText
で要素を指定(ここではtitle要素)して変数に保存。その値をログに出力
という流れ。とてもシンプル。実行するとログは以下のように出力されます。
XML名前空間で定義されている要素
title要素と同様に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行目)。これで取得できているはずなのでログを確認してみます。
とれた!\(^o^)/
これで項目取得は達成したので、後編で取得した情報をスプレッドシートに出力してみようと思います。