# #go #unmarshalling
Вопрос:
Объекты, подобные приведенным ниже, могут быть довольно легко проанализированы с помощью encoding/json
пакета.
[
{"something":"foo"},
{"something-else":"bar"}
]
Проблема, с которой я сталкиваюсь, заключается в том, что с сервера возвращается несколько диктов, подобных этой :
{"something":"foo"}
{"something-else":"bar"}
Это невозможно проанализировать с помощью приведенного ниже кода.
correct_format := strings.Replace(string(resp_body), "}{", "},{", -1)
json_output := "[" correct_format "]"
Я пытаюсь проанализировать общие данные обхода (см. Пример).
Как я могу это сделать?
Комментарии:
1. Это недопустимый json, поэтому сначала преобразуйте его в допустимый json, а затем проанализируйте его.
2. Этот JSON вообще невозможно разобрать, не говоря уже о том, чтобы легко, потому что он недействителен.
3. Json не является недействительным. На самом деле каждая строка содержит отдельный объект Json.
4. Обратите внимание, что документ по URL-адресу в вопросе содержит текстовый файл с разделителем строк JSON (т. Е. один документ JSON на строку).
5. Извините, по ошибке я отправил неправильный json
Ответ №1:
Предполагая, что ваш ввод действительно представляет собой серию действительных документов JSON, используйте json.Декодер для их декодирования:
package main
import (
"encoding/json"
"fmt"
"io"
"log"
"strings"
)
var input = `
{"foo": "bar"}
{"foo": "baz"}
`
type Doc struct {
Foo string
}
func main() {
dec := json.NewDecoder(strings.NewReader(input))
for {
var doc Doc
err := dec.Decode(amp;doc)
if err == io.EOF {
// all done
break
}
if err != nil {
log.Fatal(err)
}
fmt.Printf("% vn", doc)
}
}
Детская площадка: https://play.golang.org/p/ANx8MoMC0yq
Если ваш ввод действительно соответствует тому, что вы указали в вопросе, это не JSON, и вам нужно написать свой собственный синтаксический анализатор.
Ответ №2:
Похоже, что каждая строка является собственным объектом json.
Вам может сойти с рук следующий код, который структурирует этот вывод в правильный json:
package main
import (
"fmt"
"strings"
)
func main() {
base := `{"trolo":"lolo"}
{"trolo2":"lolo2"}`
delimited := strings.Replace(base, "n", ",", -1)
final := "[" delimited "]"
fmt.Println(final)
}
Теперь вы должны иметь возможность пользоваться encoding/json
библиотекой final
.
Ответ №3:
Другим вариантом было бы проанализировать каждую входящую строку, строку за строкой, а затем добавить каждую в коллекцию в коде (т. Е. фрагмент). Для этого Go предоставляет сканер строк.
yourCollection := []yourObject{}
scanner := bufio.NewScanner(YOUR_SOURCE)
for scanner.Scan() {
obj, err := PARSE_JSON_INTO_yourObject(scanner.Text())
if err != nil {
// something
}
yourCollection = append(yourCollection, obj)
}
if err := scanner.Err(); err != nil {
fmt.Fprintln(os.Stderr, "reading standard input:", err)
}
Ответ №4:
Вы можете прочитать ndjson из файла строка за строкой и проанализировать его, а затем применить к нему логические операции. В приведенном ниже примере вместо чтения из файла я использовал массив строк JSON.
import (
"encoding/json"
"fmt"
)
type NestedObject struct {
D string
E string
}
type OuterObject struct {
A string
B string
C []NestedObject
}
func main() {
myJsonString := []string{`{"A":"1","B":"2","C":[{"D":"100","E":"10"}]}`, `{"A":"11","B":"21","C":[{"D":"1001","E":"101"}]}`}
for index, each := range myJsonString {
fmt.Printf("Index value [%d] is [%v]n", index, each)
var obj OuterObject
json.Unmarshal([]byte(each), amp;obj)
fmt.Printf("a: %v, b: %v, c: %v", obj.A, obj.B, obj.C)
fmt.Println()
}
}
Выход:
Index value [0] is [{"A":"1","B":"2","C":[{"D":"100","E":"10"}]}]
a: 1, b: 2, c: [{100 10}]
Index value [1] is [{"A":"11","B":"21","C":[{"D":"1001","E":"101"}]}]
a: 11, b: 21, c: [{1001 101}]