我在这里看到很多关于从XML转换为JSON的帖子,我最近写了一个这样做的程序,但我也很好奇你将如何从JSON转换为XML?
示例JSON:
"version":"0.1",
"termsofService":"http://www.wunderground.com/weather/api/d/terms.html",
"features": {
"conditions": 1
}
}
, "current_observation": {
"image": {
"url":"http://icons.wxug.com/graphics/wu2/logo_130x80.png",
"title":"Weather Underground",
"link":"http://www.wunderground.com"
},
"display_location": {
"full":"Kearney, MO",
"city":"Kearney",
"state":"MO",
"state_name":"Missouri",
我不确定它是否对您有用,但我会将我的JSON发布到XML程序。
package main
import (
"fmt"
"net/url"
"encoding/xml"
"net/http"
"log"
"io/ioutil"
"encoding/json"
)
type reportType struct{
Version xml.CharData `xml:"version"`
TermsOfService xml.CharData `xml:"termsofService"
`
Features xml.CharData `xml:"features>feature"`
Full string `xml:"current_observation>display_location>full"`
StateName string `xml:"current_observation>display_location>state_name"`
WindGust string `xml:"current_observation>observation_location>full"`
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 map[string]string `json:"features"`;
CurrentObservation map[string]map[string]string `json:"current_observation"`
}
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 := "Nunna"
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= map[string]string{"feature":string(report.Features)} // allocate a map, add the 'features' value to it and assign it to output.Features
output.CurrentObservation = map[string]map[string]string {
"display_location": map[string]string {
"full": report.Full,
"state_name": report.StateName,
},"observation_location":map[string]string {"full": report.WindGust},
}
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": {
// "feature": "conditions"
// },
// "current_observation": {
// "display_location": {
// "full": "Kearney, MO",
// "state_name": "Missouri"
// },
// "observation_location": {
// "full": "HOMESTEAD HILLS, Kearney, Missouri"
// }
// }
//}
答案 0 :(得分:0)
这与进入另一个方向的过程相同。定义结构/对象以对输入进行建模(在本例中为json),创建方法以将结构中的所有值分配给您用于输出的输入,然后封送输出以获取字符串。因此,为了使用您输入的一个概念上较难的字段给出一个练习示例,将一些json解组为reportTypeJson
的实例,我可以将其分配给用于模拟xml的reportType
,如此;
report.StateName = jsonReport.CurrentObservation["display_location"]["state_name"]
这里最大的区别是代表你的xml的结构是扁平的(就像它有Something> InnerSomething> InnerInnerSomething来表示它的嵌套值,而golang中的结构没有嵌套),与json一样,你在golang中的结构倾向于具有相同数量的嵌套(如具有map [string] map [string] [string]意味着项目嵌套在主结构内部的3个级别)。您可以通过访问字段时的间接量来观察这一点,例如上面的示例中,有一个级别的间接访问CurrentObservation
但是这是一个映射的映射,因此我使用{进行索引{1}}生成display_location
的密钥,因为我正在查找statename值,我必须使用map[string]string
对其进行索引才能访问该值。
请注意,在实际程序中,需要进行大量检查,因为这些操作不安全。例如,如果json读取不包含state_name
对象,则display_location
将返回jsonReport.CurrentObservation["display_location"]
,并且尝试访问nil
将导致恐慌。
另外,请注意,在您的程序中,我建议添加两个函数,一个名为["state_name"
,另一个名为NewJsonReport(report *reportType) *reportTypeJson, err
,其中初始化/分配返回类型的新实例并返回它可以避免代码重复并使您的程序NewXmlReport(report *reportTypeJson) *reportType, err
更具可读性。在程序中的多个位置进行这种类型的分配是笨重的编码,这会增加很多维护成本,并且很可能导致错误(例如,如果其中一个模型上的某些内容发生变化或者您需要输入在整个程序中修复对它的每一个引用,而不仅仅是更新我上面提到的函数。)