2016-05-03 88 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>

就會變成

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

我得到versiontermsofservice正確的,但我無法弄清楚如何返回嵌套的像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

編輯:下面的部分是將xml類型轉換爲json類型的地方(即分配reportTypeJson的一個實例並將值從reportType分配給它,以便您可以調用json元帥來產生輸出)。假設您使用reportTypeJson的定義,其中Featuresmap[string]string,您只需修改設置爲output.Features的一行即可。在下面的示例中,我使用「複合文字」語法進行內聯。這允許您在同時爲其分配值時實例化/分配集合。

//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

非常感謝,我的最終成績也感謝你! –