4

If given the string, from a MediaWiki API request:

str = ` {
    "query": {
        "pages": {
            "66984": {
                "pageid": 66984,
                "ns": 0,
                "title": "Main Page",
                "touched": "2012-11-23T06:44:22Z",
                "lastrevid": 1347044,
                "counter": "",
                "length": 28,
                "redirect": "",
                "starttimestamp": "2012-12-15T05:21:21Z",
                "edittoken": "bd7d4a61cc4ce6489e68c21259e6e416+\\"
            }
        }
    }
}`

What can be done to get the edittoken, using Go's json package (keep in mind the 66984 number will continually change)?

waldyrious
  • 3,683
  • 4
  • 33
  • 41
Hairr
  • 1,088
  • 2
  • 11
  • 19

2 Answers2

5

When you have a changing key like this the best way to deal with it is with a map. In the example below I've used structs up until the point we reach a changing key. Then I switched to a map format after that. I linked up a working example as well.

http://play.golang.org/p/ny0kyafgYO

package main

import (
    "fmt"
    "encoding/json"
    )

type query struct {
    Query struct {
        Pages map[string]interface{}
    }
}


func main() {
    str := `{"query":{"pages":{"66984":{"pageid":66984,"ns":0,"title":"Main Page","touched":"2012-11-23T06:44:22Z","lastrevid":1347044,"counter":"","length":28,"redirect":"","starttimestamp":"2012-12-15T05:21:21Z","edittoken":"bd7d4a61cc4ce6489e68c21259e6e416+\\"}}}}`

    q := query{}
    err := json.Unmarshal([]byte(str), &q)
    if err!=nil {
        panic(err)
    }
    for _, p := range q.Query.Pages {
        fmt.Printf("edittoken = %s\n", p.(map[string]interface{})["edittoken"].(string))
    }
}
Daniel
  • 38,041
  • 11
  • 92
  • 73
  • While a map is certainly the right way to go, I would advise against using map[string]interface{}. Instead, use a map[string]page where page contains the edittoken. Example: http://play.golang.org/p/S2F0ookPHu . If you wished to be short sighted and not implement the entire page struct, you would not need to. Example: http://play.golang.org/p/w7zkAKsmwg – Stephen Weinberg Dec 15 '12 at 18:23
  • My example also doesn't panic when given malformed data. If you are going to do type assertions, use the two return syntax so that your program doesn't panic. – Stephen Weinberg Dec 15 '12 at 18:26
4

Note that if you use the &indexpageids=true parameter in the API request URL, the result will contain a "pageids" array, like so:

str = ` {
    "query": {
        "pageids": [
            "66984"
        ],
        "pages": {
            "66984": {
                "pageid": 66984,
                "ns": 0,
                "title": "Main Page",
                "touched": "2012-11-23T06:44:22Z",
                "lastrevid": 1347044,
                "counter": "",
                "length": 28,
                "redirect": "",
                "starttimestamp": "2012-12-15T05:21:21Z",
                "edittoken": "bd7d4a61cc4ce6489e68c21259e6e416+\\"
            }
        }
    }
}`

so you can use pageids[0] to access the continually changing number, which will likely make things easier.

waldyrious
  • 3,683
  • 4
  • 33
  • 41