将XML解组为接口

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

Unmarshal XML into interface

问题

如果我有一些 JSON 数据,我可以将其解组为一个空接口:

package main

import (
   "encoding/json"
   "fmt"
)

func main() {
   raw := []byte(`
   {
     "regionalRating": {"rating": "TV-PG", "region": "CA"}
   }
   `)
   {
      var rating interface{}
      json.Unmarshal(raw, &rating)
      fmt.Println(rating) // map[regionalRating:map[rating:TV-PG region:CA]]
   }
   {
      var rating map[string]interface{}
      json.Unmarshal(raw, &rating)
      fmt.Println(rating) // map[regionalRating:map[rating:TV-PG region:CA]]
   }
}

但是,如果我尝试使用相同的方法处理 XML,它会失败:

package main

import (
   "encoding/xml"
   "fmt"
)

func main() {
   raw := []byte(`
   <regionalRating>
      <rating>TV-PG</rating>
      <region>CA</region>
   </regionalRating>
   `)
   {
      var rating interface{}
      xml.Unmarshal(raw, &rating)
      fmt.Println(rating) // <nil>
   }
   {
      var rating map[string]interface{}
      xml.Unmarshal(raw, &rating)
      fmt.Println(rating) // map[]
   }
}

我记得在这里看到过有人找到了一种类似于我的代码的方法来解决这个问题。这种方法可行吗?

英文:

If I have some JSON, I can Unmarshal into an empty interface:

package main

import (
   &quot;encoding/json&quot;
   &quot;fmt&quot;
)

func main() {
   raw := []byte(`
   {
     &quot;regionalRating&quot;: {&quot;rating&quot;: &quot;TV-PG&quot;, &quot;region&quot;: &quot;CA&quot;}
   }
   `)
   {
      var rating any
      json.Unmarshal(raw, &amp;rating)
      fmt.Println(rating) // map[regionalRating:map[rating:TV-PG region:CA]]
   }
   {
      var rating map[string]any
      json.Unmarshal(raw, &amp;rating)
      fmt.Println(rating) // map[regionalRating:map[rating:TV-PG region:CA]]
   }
}

but if I try the same thing with XML, it fails:

package main

import (
   &quot;encoding/xml&quot;
   &quot;fmt&quot;
)

func main() {
   raw := []byte(`
   &lt;regionalRating&gt;
      &lt;rating&gt;TV-PG&lt;/rating&gt;
      &lt;region&gt;CA&lt;/region&gt;
   &lt;/regionalRating&gt;
   `)
   {
      var rating any
      xml.Unmarshal(raw, &amp;rating)
      fmt.Println(rating) // &lt;nil&gt;
   }
   {
      var rating map[string]any
      xml.Unmarshal(raw, &amp;rating)
      fmt.Println(rating) // map[]
   }
}

I remember seeing an answer on here where someone had found a method to do this,
using something similar to my code. Is it possible?

答案1

得分: 1

不,根据文档中的第一行,这是不可能的:

Unmarshal解析XML编码的数据,并将结果存储在指向v的值中,v必须是任意的结构体、切片或字符串。

需要注意的是,如果你想将XML解析为任意类型,你需要自己实现解析过程。不过,这并不太困难,因为XML的标记化已经由Decoder.Token方法完成,你只需要查看每个标记并决定如何处理它。

英文:

> Is it possible?

No, it is not possible, at least not according to the first line in the doc:

> Unmarshal parses the XML-encoded data and stores the result in the value pointed to by v, which MUST be an arbitrary struct, slice, or string.

<sup>emphasis added by me</sup>


If you want to unmarshal the XML into an arbitrary type you'll need to implement the unmarshaling yourself. This is not too difficult however since the tokenization of the XML is already done for you by the Decoder.Token method, all that's left for you to do is to look at each token and decide what to do with it.

huangapple
  • 本文由 发表于 2023年3月13日 04:38:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/75716245.html
匿名

发表评论

匿名网友

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

确定