2016-05-03 24 views
0

こんにちはStackOverFLowers !!GOLang:ネストされたXMLからJSON

私はXML入力をどのようにしてGOlangを使用してJSONに変換するかを理解しようとしています。たとえば...

<version>0.1</version> <termsofService>http://www.wunderground.com/weather/api/d/terms.html</termsofService> <features> <feature>conditions</feature> </features>

は私が正しくversiontermsofserviceを取得していますが、私のようなネストされたものを返す方法を見つけ出すことはできません

"version": "0.1", "termsofService": "http://www.wunderground.com/weather/api/d/terms.html", "features": { "feature": "conditions" },

に変えることでしょうfeatures。私はハードコードする必要がありますか?

CODE:

type reportType struct{ 
    Version xml.CharData  `xml:"version"` 
    TermsOfService xml.CharData `xml:"termsofService" 
    ` 
    Features xml.CharData  `xml:"features>feature"` 
    Zip  xml.CharData  `xml:"current_observation>display_location>zip"` 
    Problem myErrorType  `xml:"error"` 
} 
type myErrorType struct{ 
    TypeOfError xml.CharData `xml:"type"` 
    Desciption xml.CharData `xml:"description"` 
} 
type reportTypeJson struct{ 
    Version  string `json:"version"`; 
    TermsOfService string `json:"termsofService"`; 
    Features string `json:"features feature" `; 
    Zip   string `json:"current_observation > display_location > zip"`; 
} 
func main() { 
    fmt.Println("data is from WeatherUnderground.") 
    fmt.Println("https://www.wunderground.com/") 
    var state, city string 
    str1 := "What is your state?" 
    str2 := "What is your city?" 
    fmt.Println(str1) 
    fmt.Scanf("%s", &state) 
    fmt.Println(str2) 
    fmt.Scanf("%s", &city) 
    baseURL := "http://api.wunderground.com/api/"; 
    apiKey := "YouDontNeedToKnow" 
    var query string 

    //set up the query 
    query = baseURL+apiKey + 
    "/conditions/q/"+ 
    url.QueryEscape(state)+ "/"+ 
    url.QueryEscape(city)+ ".xml" 
    fmt.Println("The escaped query: "+query) 

    response, err := http.Get(query) 
    doErr(err, "After the GET") 
    var body []byte 
    body, err = ioutil.ReadAll(response.Body) 
    doErr(err, "After Readall") 
    fmt.Println(body); 
    fmt.Printf("The body: %s\n",body) 

    //Unmarshalling 
    var report reportType 
    xml.Unmarshal(body, &report) 
    fmt.Printf("The Report: %s\n", report) 
    fmt.Printf("The description is [%s]\n",report.Problem.Desciption) 

    //Now marshal the data out in JSON 
    var data []byte 
    var output reportTypeJson 
    output.Version = string(report.Version); 
    output.TermsOfService = string(report.TermsOfService) 

    output.Features= string(report.Features) 
    output.Zip=string(report.Zip) 
    data,err = json.MarshalIndent(output,"","  ") 
    doErr(err, "From marshalIndent") 
    fmt.Printf("JSON output nicely formatted: \n%s\n",data) 


} 
func doErr(err error, message string){ 
    if err != nil{ 
     log.Panicf("ERROR: %s %s \n", message, err.Error()) 
    } 


} 

OUTPUT:お時間を

JSON output nicely formatted: { "version": "0.1", "termsofService": "http://www.wunderground.com/weather/api/d/terms.html", "features \u003e feature": "conditions", "current_observation \u003e display_location \u003e zip": "64068" }

ありがとう!

答えて

1

json構造体の定義が正しくないため、希望する出力が得られません。あなたが持っている;

type reportTypeJson struct{ 
    Version  string `json:"version"`; 
    TermsOfService string `json:"termsofService"`; 
    Features string `json:"features feature" `; 
    Zip   string `json:"current_observation > display_location > zip"`; 
} 
オブジェクトを文字列としての機能を示したが、それは実際にだ

、どちらかmap[string]stringかなどのように定義されるだろう、それ自身の構造体。

type Features struct { 
    Feature string `json:"feature"` 
} 

は、フィールド名が複数である考えると、私はあなたが探しているものはおそらくです

type reportTypeJson struct{ 
    Version  string `json:"version"`; 
    TermsOfService string `json:"termsofService"`; 
    Features map[string]string `json:"features"`; 
    Zip   string `json:"current_observation > display_location > zip"`; 
} 

にので、あなたの構造体を変更収集するためのものですよね。もちろん、これは、xml構造体の値をjsonのものに代入する他のコードを変更する必要があることを意味しますが、私はあなた自身でそれを正しく理解することができます:D

EDIT:以下のセクションxml型をjson型に変換する場所です(つまり、reportTypeJsonのインスタンスを割り当て、reportTypeから値を代入してjsonマーシャリングを呼び出して出力することができます)。あなたがFeaturesmap[string]stringとした上記のreportTypeJsonの定義を使用していると仮定すると、output.Featuresを設定した1行を修正するだけです。以下のサンプルでは、​​これを '複合リテラル'構文でインライン展開します。これにより、同時にコレクションに値を割り当てながらコレクションをインスタンス化/割り当てすることができます。

//Now marshal the data out in JSON 
var data []byte 
var output reportTypeJson 
output.Version = string(report.Version); 
output.TermsOfService = string(report.TermsOfService) 

output.Features= map[string]string{"features":string(report.Features)} // allocate a map, add the 'features' value to it and assign it to output.Features 
output.Zip=string(report.Zip) 
data,err = json.MarshalIndent(output,"","  ") 
doErr(err, "From marshalIndent") 
fmt.Printf("JSON output nicely formatted: \n%s\n",data) 
+0

私があなたの注意を失う前に、あなたが示唆したことを受け入れるためにコードを修正する方法の例を教えていただけますか?私は最終的な明日があり、私はまだコンセプトを完全に把握しようとしています –

+0

@BeccaBohemええ、確かに、私はコードのその部分を調べることができる前に会議に行きました。私はその部分でも今編集します。 – evanmcdonnal

+0

ありがとう、私の最終学年もあなたに感謝! –

関連する問題