Hello StackOverFLowers !!
我试图弄清楚如何给出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" },
我正确地获得了version
和termsofservice
,但我无法弄清楚如何返回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())
}
}
输出:
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"
}
谢谢你的时间!
答案 0 :(得分: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 marshal来生成输出) 。假设您使用上面reportTypeJson
的定义Features
作为map[string]string
,您只需要修改设置output.Features
的一行。在下面的示例中,我使用'composite literal'语法内联。这允许您在同时为其分配值时实例化/分配集合。
//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)