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^)/
これで項目取得は達成したので、後編で取得した情報をスプレッドシートに出力してみようと思います。