2024年5月20日 星期一

處理 xml 格式 (例如 vlc 的播放清單) 較好走的繞路: 轉成 json 格式、 撈出一些欄位、 再轉成 csv 檔

XML 格式的檔案很難處理。 以前我試過 xmlstarlet, 覺得有點複雜, 而且找不太到教學文。 還好大部分時候不太會遇到需要批次 編輯 xml 檔的情況。 如果只是想要從 xml 檔案裡面 撈出部分欄位, 那麼用 xq 指令先把它轉成 jq 格式, 簡單多了!

在 vlc 裡建立播放清單 這次要處理的範例檔是 news-channels.xspf。 這是從 「線上看電視」 裡面的一些新聞台 youtube 頻道連結所產生的 vlc 播放清單檔。 [6/9 才發現:不知為何, <localtion> 欄位變成一長串奇怪的網址,讓vlc無法播放。 已手動編輯,拿<info>欄位的值copy過來覆蓋掉。] 如果你要建立自己的版本, 可以:

  1. 在 vlc 裡面按 ctrl-L 或 「檢視」=>「播放清單」, 叫出播放清單的編輯畫面。
  2. 按滑鼠右鍵選 「進階開啟」。
  3. 在 「網路」 分頁底下可以貼上某新聞頻道的 youtube 網址。 剛貼上時, vlc 會直接拿網址的後半段來當作標題。 不需要急著去手動編輯它。
  4. 重複上述步驟。 每加入幾個網址趕快先按右鍵 「儲存播放清單至檔案」 才是最重要的。 儲存時, 選擇 xspf 檔案格式。
  5. 至於標題, 只要點進去看過一次, 再按 ctrl-L 鍵回到播放清單的編輯畫面, 那一個頻道的標題就會自動更新成該 youtube 頻道自己設定的文字。

我本來是想拿它來當選單, 看可不可以略過瀏覽器, 直接用 vlc 任意選新聞頻道。 但是 vlc 的播放清單是拿來 按順序播放用的, 若想要任意切換, 步驟有點囉嗦, 不太符合我的需求。 所以接下來的目標是從 news-channels.xspf 這個 xml 檔裡面抓出網址和頻道的標題, 變成一個 csv 檔, 以便餵給我用 easybashgui 函式庫 所寫的選單小程式。

再來, 安裝 yq 套件: apt install yq 此時系統也會順便安裝 jq 套件。 這個 yq 採用 jq 當引擎, 專門用來處理 yaml/xml/toml 檔。 我們要用的是 yq 套件當中所提供的 xq-python 指令 (在 yq 專案官網的原名就叫 xq; 但是我猜是因為 debian 套件管理者為了避免與另一個 「以 golang 撰寫、 名為 xq」 的專案衝突, 所以改名) xq-python . news-channels.xspf 光是這樣就已經可以把 xml 轉成 json, 後續容易處理多了。 更好的是: 其實也不必把結果 pipe 給 jq, 因為 xq-python 本身就接跟 jq 相同的語法。 所以可以檢視一下上面指令的輸出, 指認出我們想要的欄位, 重下一次指令: xq-python .playlist.trackList.track news-channels.xspf 再來一次: xq-python '.playlist.trackList.track | map([.info, .title])' news-channels.xspf 得到一個二維陣列, 幾乎就是我們要的結果了。

最後一步, 可以 用 zq 把那個二維陣列轉成 csv 檔。 不過既然都已經用 jq 語法了, 那就用到底吧。 根據 這則留言 裡面的範例, 用 jq 把二維陣列轉成 csv 的公式如下: 二維陣列 | map(@csv) | .[] 因為 jq 的 @csv 函數每次處理一列, 而不是一口氣處理整個二維陣列! 又因為 @csv 會產生一些多餘的字元, 所以還要用 regexp 把那些字元砍掉。 最終指令: xq-python '.playlist.trackList.track | map([.info, .title]) | map(@csv) | .[]' news-channels.xspf | perl -pe 's/[\\"]//g' > news-channels.csv

是說.. 盡管老婆最後還是決定直接用瀏覽器看, 一時之間讓我覺得好像踩空步伐、 差點掉出玻璃心, 但至少我因此學會用簡單的方式處理 xml 檔, 還是很值得!

沒有留言:

張貼留言

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