2021年9月3日 星期五

xml-js 把 xml 轉成 json / jq 批次串接多個檔 / 噗浪 rss 備份

先前我一直用 plurk-list 這個 php 小程式從噗浪所提供的 rss 來備份我自已的噗浪。 可是最近突然失效了。 原來是噗浪的 rss 格式有小的變動, 時間順序變顛倒了。 反正我本來就不喜歡 php 語言, 乾脆整個重寫。 Rss 是 xml 格式, 但是處理 xml 格式的程式寫起來很囉嗦。 秉持著 長線投資的電腦學習策略 所建議的 「以檔案格式為核心」 的思考原則, 決定先把 xml 轉成 json 再來處理, 畢竟有 jq 瑞士刀 可以處理 json 檔, 而且 json 格式在許多語言裡面直接對應到普通陣列與關聯陣列, 處理起來方便多了。 這篇其實包含三個不同的主題, 可以視興趣選讀 1、2 節或 1、3 節。

一、 xml 轉 json

我們拿噗浪的 rss 檔來作為 xml 資料檔的範例, 例如 ckhung0 最近的噗。 實際上我是每週備份: (寫在一個被 cron 呼叫的 script 裡面): wget http://www.plurk.com/ckhung0.xml -O /home/ckhung/plurklogs/$(date '+%y%W').xml 這樣就會產生一堆 *.xml 檔。 作實驗當然沒空等 cron, 大家可以改下載好幾位用戶的 rss, 以下假設你已準備好 ckhung0.xml、 davelin.xml、 MGdesigner.xml、 aboutfish.xml 等等。 (只是拿我的噗友舉例)

搜尋 xml 轉 json 時, 遇到 這一頁下載趨勢比較圖 , 那就決定從眾採用 xml-js 了:

sudo npm install -g xml-js
xml-js 2117.xml --compact		# 輸出擠成一團,不好讀
xml-js 2117.xml --compact | jq .	# 用 jq 縮排, 漂亮多了

根據 官網的說明, 處理比較複雜的 xml 時, 不能指定精簡輸出模式 --compact 。 我們的 rss 很簡單, 當然就採用 --compact 囉。

很多類型的檔案其實都是 xml 檔, 例如 svg 就是。 不過必須先把檔名改成 ,xml , xml-jq 才願意轉檔。 比方說把 這張圖 存檔命名為 graphic-workflow.xml 就可以抓出 svg 圖片當中大多數 「被楕圓形圈起來的文字」: xml-js graphic-workflow.xml --compact | jq '.svg.g.g | map([.title._text, .ellipse]) | map(select(.[1]!=null)) | map(.[0])' 有一些抓不到, 是因為製圖時採用不同的順序。 隨便啦, 總之這一段的重點是: xml-jq 可以把 svg、 xhtml、 mathml、 gpx、 kmx 等等各種 xml 檔轉成 json, 然後 jq 就可以接手。

二、 jq 批次串接多個檔

回到噗浪的 rss。 假設已有很多個 xml 檔, 裡面個含有許多筆噗, 我們想把全部的噗全部塞進一個 json 檔, 該怎麼做? 先把所有的 xml 轉成 json:

for f in *.xml ; do xml-js $f --compact | jq . > ${f/%xml/json} ; done
# 或是這樣也可以 (建議第一次做先不要 pipe 給 bash, 先查看印出來的指令是否正確)
ls *.xml | perl -ne 'print "xml-js $1.xml --compact | jq . > $1.json\n" if /(.*)\.xml/' | bash

要合併兩三個檔案可以這樣做:

jq -s '.[0].feed.entry + .[1].feed.entry + .[2].feed.entry' \
    ckhung0.json davelin.json MGdesigner.json

你可以在最後面接上 | jq 'length' 數一下串起來的結果是否筆數正確。 但是如果有三十個或三百個檔要串接呢? jq 有一個強大的 reduce 功能:

jq -s 'reduce .[] as $item ([]; . + $item.feed.entry)' *.json | jq length

不過因為我用 cron 定期抓回來的 rss 裡面會有重覆的資料, 還要處理輸出格式的問題, 所以不適合全程用 jq 做。 還是寫 python 程式好了。

三、 噗浪的 rss => json 再轉 html

這一節, 噗浪的 rss 就不是範例而是主角了。 假設你已按照第二節前半部從產生很多 json 檔。 接下來請下載 prj2html.py (用 python 寫程式比用 php 愉快多了!) 然後 python3 prj2html.py *.json > new.html 就可以手動編輯 new.html 再把它貼到你的噗浪 html 備份了。

沒有留言:

張貼留言

因為垃圾留言太多,現在改為審核後才發佈,請耐心等候一兩天。