19410


例えば、下記URL(MediaWiki API)にあるようなJsonのキーの値が数字になっていて変動するものはどのようにパースすればいいのでしょうか。

[https://ja.wikipedia.org/w/api.php?format=json&action=query&prop=categories&titles=%E3%83%89%E3%83%A9%E3%81%88%E3%82%82%E3%82%93](https://ja.wikipedia.org/w/api.php?format=json&action=query&prop=categories&titles=%E3%83%89%E3%83%A9%E3%81%88%E3%82%82%E3%82%93)

**レスポンス**

[code]

    {
    "continue": {
    "clcontinue": "2222571|小学館の学年誌の漫画作品",
    "continue": "||"
    },
    "query": {
    "pages": {
    // このキーが変動する
    "2222571": {
    "pageid": 2222571,
    "ns": 0,
    "title": "ドラえもん",
    "categories": [
    {
    "ns": 14,
    "title": "Category:SF漫画作品"
    },
    {
    "ns": 14,
    "title": "Category:いたずら・ぶっく"
    },
    {
    "ns": 14,
    "title": "Category:めばえ"
    },
    {
    "ns": 14,
    "title": "Category:コロコロコミックの漫画作品"
    },
    {
    "ns": 14,
    "title": "Category:タイムトラベルを題材とした漫画作品"
    },
    {
    "ns": 14,
    "title": "Category:ドラえもん"
    },
    {
    "ns": 14,
    "title": "Category:ネコを主人公にした物語"
    },
    {
    "ns": 14,
    "title": "Category:出典を必要とする記述のある記事/2010年11月"
    },
    {
    "ns": 14,
    "title": "Category:外部リンクがリンク切れになっている記事/2015年4月"
    },
    {
    "ns": 14,
    "title": "Category:小学校を舞台とした漫画作品"
    }
    ]
    }
    }
    }
    }
    
[/code]

できればGolangでのやり方をお教えいただけると助かりますが、他の言語での方法でも構いません。  
ちなみに自分は下記コードでできると考え実行しましたができませんでした。何か方法があるのであれば教えて下さい。

**私が考えたコード**

[code]

    package main
    
    import (
        "fmt"
        "github.com/bitly/go-simplejson"
        "io/ioutil"
        "net/http"
        "net/url"
    )
    
    func main() {
        values := url.Values{}
        values.Add("format", "json")
        values.Add("action", "query")
        values.Add("prop", "categories")
        values.Add("titles", "ドラえもん")
    
        resp, err := http.Get("https://ja.wikipedia.org/w/api.php?" + values.Encode())
        if err != nil {
            fmt.Println(err)
        }
    
        defer resp.Body.Close()
        rf, err := ioutil.ReadAll(resp.Body)
        if err != nil {
            fmt.Println(err)
        }
        js, err := simplejson.NewJson(rf)
        if err != nil {
            fmt.Println(err)
        }
    
        pageID := js.Get("query").Get("pages")
        fmt.Println(pageID)
        category, err := pageID.Get("categories").GetIndex(1).Get("title").String()
        if err != nil {
            fmt.Println(err)
        }
    
        fmt.Println(category)
    
    }
    
[/code]


CC BY-SA 3.0
2015-11-28T05:49:51.843
19393
2015-11-28T12:03:19.687
7232
question
go json
キーが変動するJsonをパースしたい


ゴリ押しですができる方法を見つけました。

**コード**

[code]

    package main
    
    import (
        "fmt"
        "github.com/bitly/go-simplejson"
        "io/ioutil"
        "net/http"
        "net/url"
        "regexp"
    )
    
    func main() {
        values := url.Values{}
        values.Add("format", "json")
        values.Add("action", "query")
        values.Add("prop", "categories")
        values.Add("titles", "ドラえもん")
    
        resp, err := http.Get("https://ja.wikipedia.org/w/api.php?" + values.Encode())
        if err != nil {
            fmt.Println(err)
        }
    
        defer resp.Body.Close()
        rf, err := ioutil.ReadAll(resp.Body)
        if err != nil {
            fmt.Println(err)
        }
        js, err := simplejson.NewJson(rf)
        if err != nil {
            fmt.Println(err)
        }
    
        re1, _ := regexp.Compile("\\|.*")
    
        pageID, err := js.Get("continue").Get("clcontinue").String()
        if err != nil {
            fmt.Println(err)
        }
    
        category, err := js.Get("query").Get("pages").Get(re1.ReplaceAllString(pageID, "")).Get("categories").GetIndex(1).Get("title").String()
        if err != nil {
            fmt.Println(err)
        }
    
        re2, _ := regexp.Compile("Category:")
        converted := re2.ReplaceAllString(category, "")
    
        fmt.Println(converted)
    
    }
    
[/code]


CC BY-SA 3.0
2015-11-28T06:01:18.260
19394
2015-11-28T06:01:18.260
7232
19393
answer


一旦 `map` に変換して、マップ・キーを取り出すのはどうでしょうか。

[code]

    func main() {
    
                   :
      js, err := simplejson.NewJson(rf)
      if err != nil {
        log.Fatalln(err)
      }
    
      // Cast to map
      m, err := js.GetPath("query", "pages").Map()
      if err != nil {
        log.Fatalln(err)
      }
    
      // Get map keys
      keys := make([]string, 0, len(m))
      for k, _ := range m {
        keys = append(keys, k)
      }
    
      // Reach to title
      title, err := js.GetPath("query", "pages", keys[0], "categories").
        GetIndex(1).Get("title").String()
      if err != nil {
        log.Fatalln(err)
      }
      title = strings.Split(title, ":")[1]
      fmt.Println(title)
    
[/code]


CC BY-SA 3.0
2015-11-28T12:03:19.687
19410
2015-11-28T12:03:19.687
19393
answer