2015-04-30 4 views
0

Я новичок в Go и пытаюсь выяснить, как вывести необработанный внутренний JSON «{\" data \ ": \" Некоторые данные "}" из раздела "Внешнее". До сих пор, не повезло ...Golang return inested JSON

Это не входные данные:

{ 
"Outer": "{\"data\":\"Some data\"}" 
} 

То, что я хотел бы получить следующая в виде строки с косой черты:

{\"data\":\"Some data\"} 
+1

см http://stackoverflow.com/questions/21268000/unmarshaling-nested-json-objects-in-golang – Makpoc

+0

возможно дубликат http://stackoverflow.com/questions/16674059/how-to-access-deep-nested-json-keys-and-values ​​ –

ответ

2

Если вы знать ключ («Outer»), вы можете сделать это следующим образом (on the Playground):

package main 

import (
    "encoding/json" 
    "fmt" 
) 

func main() { 
    //Creating the maps for JSON 
    m := map[string]json.RawMessage{} 

    //Parsing/Unmarshalling JSON encoding/json 
    err := json.Unmarshal([]byte(input), &m) 

    if err != nil { 
     panic(err) 
    } 
    fmt.Printf("%s", m["Outer"]) 
} 

const input = ` 
{ 
"Outer": "{\"data\":\"Some data\"}" 
} 
` 

Обратите внимание, что ваш пример JSON является м Исходя из окончательного выхода после данных. Без этого вы получите сообщение об ошибке.

Если вы не знаете свою структуру, см. this reply, как это сделать с произвольными вложенными данными.

+0

Ваш код почти то, что мне нужно, однако он возвращает данные ** без ** косых черт. Есть ли способ заставить его хранить данные точно так же, как '{\" data \ ": \" Некоторые данные \ "}' возвращаются в виде строки? –

+0

Да, 2 небольших изменения сделают это. См. Отредактированный ответ. Определение карты меняется на использование 'json.RawMessage' и' fmt.Printf' используется для печати сообщения. – IamNaN

+0

Удивительный! Спасибо за вашу помощь! У меня есть еще один вопрос для вас. Как я могу хранить '{\" data \ ": \" Некоторые данные \ "}' в переменной (с включенными косыми чертами)? –

2

Это началось как просто комментарий на previous answer, но росло.

Хотя вы можете распаковать во временный map[string]interface{} (или map[string]json.RawMessage), что может сделать много дополнительной работы, если есть другие «внешние» поля, которые вы просто хотите, чтобы игнорировать, и это также требует проверки типа, который был найден (например, для случая плохого/неожиданного ввода, например {"Outer": 42}). Это, вероятно, означает, добавив что-то вроде этого к предыдущему ответу:

str, ok := m["Outer"].(string) 
    if !ok { return errors.New("…") } 
    err := json.Unmarshal([]byte(str), &actual) 

Намного проще, вероятно, использовать временный тип оберточной так:

var tmp struct{ Outer string } 
    err := json.Unmarshal(b, &tmp) 
    if err != nil { … } 

    var data actualType 
    err := json.Unmarshal([]byte(tmp.Outer), &data) 

Вы можете либо сделать это в отдельной функции, возвращает желаемый тип (или ошибку, например func foo(b []byte) (actualType, error)). Или вы можете поместить это изменение в пользовательский метод UnmarshalJSON на тип обертки, чтобы реализовать json.Unmarshaler. Вы также можете сделать обратный, если хотите, чтобы вы могли вернуться в тот же формат.

Полные Runnable примеры на детской площадке: https://play.golang.org/p/IXU2koyJ1A

+0

Обратите внимание, что это отвечает на исходный вопрос, а не на измененный/отредактированный вопрос. –

+0

Я очень ценю примеры, они могут оказаться действительно полезными, когда мне нужно сломать и манипулировать JSON в будущем! –