Best way to construct XML from JSON in Golang

huangapple go评论83阅读模式
英文:

Best way to construct XML from JSON in Golang

问题

我有一个中间件,我在其中接收JSON输入和用户凭据,并需要提取它们以构建包含其他各种数据的完整XML。

假设我有以下代码来解码JSON:

json.NewDecoder(r.Request.Body).Decode(entityPointer)

从这里构建XML的最有效方法是什么?

我想我可以通过匹配结构体并使用它们,或者使用现有的XML模板解析它们并替换模板变量来实现。

例如,如果我有一个请求{username: '11', password: 'pass'},我该如何构建以下XML:

英文:

I have a middleware where I receive JSON input and with user credentials and needs to grab them to construct a full XML with various other data.

Suppose I have below code to decode JSON:

json.NewDecoder(r.Request.Body).Decode(entityPointer)

What is the most efficient way to construct XML from here?

I thought I could just match with struct and use them or parse them with existing XML template and replace the template variables?

if I had for example {username: '11', password: 'pass'} as request, How can I construct below XML out of

答案1

得分: 1

你可以在XML和JSON中使用相同的结构体,例如:

type Person struct {
    Id        int    `xml:"id,attr"`
    FirstName string `xml:"name>first" json:"first"`
    LastName  string `xml:"name>last" json:"last"`
}

func main() {
    j := `{"id": 10, "first": "firstname", "last":"lastname"}`
    var p Person
    fmt.Println(json.Unmarshal([]byte(j), &p), p)
    out, _ := xml.MarshalIndent(p, "\t", "\t")
    fmt.Println(string(out))
}

playground

在http://golang.org/pkg/encoding/xml/#example_Encoder中查看XML示例。

//编辑

嗯,既然你已经有一个模板,你可以使用html/template,例如:

const xmlTmpl = `<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE api SYSTEM "api.dtd">
<api version="6.0">
    <request>
        <reqClient returnToken="N">
            <user>{{.AdminUsername}} </user>
            <password>{{.AdminPassword}}</password>
        </reqClient>
        <reqValidate returnBalance="Y">
            <userName>{{.Username}}</userName>
            <password>{{.Password}}</password>
            <channel>M</channel>
        </reqValidate>
    </request>
</api>
`

var tmpl = template.Must(template.New("foo").Parse(xmlTmpl))

type Entity struct {
    AdminUsername string `json:"-"`
    AdminPassword string `json:"-"`
    Username, Password string
}

func main() {
    e := Entity{Username: "User", Password: "Loser"}
    //json.NewDecoder(r.Request.Body).Decode(&e)
    e.AdminUsername = "admin" // 在解析请求后填充管理员用户名/密码
    e.AdminPassword = "admin-password"
    fmt.Println(tmpl.Execute(os.Stdout, e))
}
英文:

You can use the same struct for both XML and JSON, for example:

type Person struct {
	Id        int    `xml:&quot;id,attr&quot;`
	FirstName string `xml:&quot;name&gt;first&quot; json:&quot;first&quot;`
	LastName  string `xml:&quot;name&gt;last&quot; json:&quot;last&quot;`
}

func main() {
	j := `{&quot;id&quot;: 10, &quot;first&quot;: &quot;firstname&quot;, &quot;last&quot;:&quot;lastname&quot;}`
	var p Person
	fmt.Println(json.Unmarshal([]byte(j), &amp;p), p)
	out, _ := xml.MarshalIndent(p, &quot;\t&quot;, &quot;\t&quot;)
	fmt.Println(string(out))

}

<kbd>playground</kbd>

Check the xml examples @ http://golang.org/pkg/encoding/xml/#example_Encoder

//edit

Well, since you already have a template you could use html/template, for example:

const xmlTmpl = `&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;!DOCTYPE api SYSTEM &quot;api.dtd&quot;&gt;
&lt;api version=&quot;6.0&quot;&gt;
    &lt;request&gt;
&lt;reqClient returnToken=&quot;N&quot;&gt;
    &lt;user&gt;{{.AdminUsername}} &lt;/user&gt;
    &lt;password&gt;{{.AdminPassword}}&lt;/password&gt;
&lt;/reqClient&gt;&lt;reqValidate returnBalance=&quot;Y&quot;&gt;
    &lt;userName&gt;{{.Username}}&lt;/userName&gt;
    &lt;password&gt;{{.Password}}&lt;/password&gt;
    &lt;channel&gt;M&lt;/channel&gt;
&lt;/reqValidate&gt;&lt;/request&gt;
&lt;/api&gt;
`

var tmpl = template.Must(template.New(&quot;foo&quot;).Parse(xmlTmpl))

type Entity struct {
	AdminUsername      string `json:&quot;-&quot;`
	AdminPassword      string `json:&quot;-&quot;`
	Username, Password string
}

func main() {
	e := Entity{Username: &quot;User&quot;, Password: &quot;Loser&quot;}
	//json.NewDecoder(r.Request.Body).Decode(&amp;e)
	e.AdminUsername = &quot;admin&quot; // fill admin user/pass after parsing the request
	e.AdminPassword = &quot;admin-password&quot;
	fmt.Println(tmpl.Execute(os.Stdout, e))
}

huangapple
  • 本文由 发表于 2014年9月18日 06:46:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/25901566.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定