Go
XML
golang
JSON
cli

golangでxmlをjsonにして取得するコマンドラインツールを作った

golangでxmlをjsonにして取得するコマンドラインツールを作ってみたことがありました。

golangはcli toolがすぐに作れるのでいいですね。私がcli toolを作成する時によく使用するのはurfave/cliですが、他のものもたくさんあります。

今回は主にurfave/cliとかmmcdole/gofeedとかの使い方の紹介みたいな感じになると思います。(と言っても、READMEドキュメントに書いてあるけど)

xq.go
package main

import (
    "fmt"
    "os"
    "encoding/json"
    "github.com/urfave/cli"
    _ "reflect"
    gofeed "github.com/mmcdole/gofeed"
)

func Action(c *cli.Context) {
    app := App()
    if c.Args().Get(0) == "" {
        help := []string{"", "--help"}
        app.Run(help)
        os.Exit(1)
    }
}

func App() *cli.App {
    app := cli.NewApp()
    app.Name = "xq"
    app.Usage = "xq j /path/to/rss.xml"
    app.Version = "0.0.1"
    app.Author = "syui"
    return app
}

type RssItem struct {
    Title       string `json:"title"`
    Link        string `json:"link"`
    Updated     string `json:"update"`
    Published   string `json:"publish"`
}

type RssItems []RssItem

func (b RssItems) Len() int {
    return len(b)
}

func main() {
    app := App()
    app.Action = Action
    app.Commands = []cli.Command{
        {
            Name:    "json",
            Aliases: []string{"j"},
            Usage:   "xq j ./index.xml #json output",
            Action:  func(c *cli.Context) error {
                file, _ := os.Open(c.Args().First())
                defer file.Close()
                fp := gofeed.NewParser()
                feed, _ := fp.Parse(file)
                items := feed.Items
                outputJson, err := json.Marshal(&items)
                if err != nil {
                    panic(err)
                }
                //w.Header().Set("Content-Type", "application/json")
                fmt.Printf("%s", string(outputJson))
                return nil
            },
        },
        {
            Name:    "latest",
            Aliases: []string{"l"},
            Usage:   "xq l ./index.xml #latest updated",
            Action:  func(c *cli.Context) error {
                file, _ := os.Open(c.Args().First())
                defer file.Close()
                fp := gofeed.NewParser()
                feed, _ := fp.Parse(file)
                fmt.Println(feed.Updated)
                return nil
            },
        },
    }
    app.Run(os.Args)
}

使い方は至ってシンプルで、まずオプションを使用して、次にxmlファイルを指定する感じ。

$ url=https://syui.gitlab.io/test-hugo-theme-wave/index.xml
$ curl -sSL -H "Accept: application/xml" $url -o index.xml
$ cat index.xml

$ go run xq.go j ./index.xml
$ go build

$ xq j ./index.xml
{"title":"Creating a new theme","link":"https://syui.gitlab.io/test-hugo-theme-wave/2016/01/01/creating-a-new-theme/","date":"2018-01-16T00:00:00.000+09:00"}
{"title":"Archive","link":"https://syui.gitlab.io/test-hugo-theme-wave/archive/","date":"2018-01-16T00:00:00.000+09:00"}

なんか色々とあれだと思うのでPRとかあれば喜びます。

https://gitlab.com/syui/xq

download

$ go get -u -v gitlab.com/syui/xq