Golang的Unmarshal Json无法解析所有子结构。

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

Golang Unmarshal Json is not parsing all the child structure

问题

我有一个父结构体和两个子结构体ResponseA和ResponseB。我为ParentA结构体编写了"UnmarshalJson"函数。但是ParentB结构体和字符串字段没有解析。我该如何编写自定义的Unmarshal函数,只解析指定的结构体?

  1. type ResponseA struct {
  2. PageA int `json:"pageA"`
  3. EntriesA []string `json:"entriesA"`
  4. }
  5. type ResponseB struct {
  6. PageB int `json:"pageB"`
  7. EntriesB []string `json:"entriesB"`
  8. }
  9. type ResponseParent struct {
  10. ResponseA
  11. ResponseB
  12. PageC int `json:"pageC"`
  13. }
  14. func (r *ResponseA) UnmarshalJSON(data []byte) error {
  15. // 解析ResponseA结构体的逻辑
  16. }
  17. func main() {
  18. jsonStr := `{"pageA": 1, "entriesA": ["classA"], "pageB": 2, "entriesB": ["classC","classD"], "pageC":3}`
  19. // str := `{"page": 1, "entries": ["classA", "classB"]}`
  20. var res *ResponseParent
  21. json.Unmarshal([]byte(jsonStr), &res)
  22. entriesA := res.EntriesA
  23. pageA := res.PageA
  24. entriesB := res.EntriesB
  25. pageB := res.PageB
  26. pageC := res.PageC
  27. fmt.Println("========Response A==========")
  28. fmt.Println("PageA:", pageA)
  29. fmt.Println("EntriesA:", entriesA)
  30. fmt.Println("========Response B==========")
  31. fmt.Println("PageB:", pageB)
  32. fmt.Println("EntriesB:", entriesB)
  33. fmt.Println("PageC:", pageC)
  34. }
  35. 输出结果
  36. ========Response A==========
  37. PageA: 1
  38. EntriesA: [classA]
  39. ========Response B==========
  40. PageB: 0
  41. EntriesB: []
  42. PageC: 0

你可以在UnmarshalJSON函数中编写解析ResponseA结构体的逻辑,然后在main函数中使用json.Unmarshal解析整个JSON字符串。这样,只有ResponseA结构体会被解析,而ResponseB结构体和其他字段将保持为默认值。

英文:

I have one parent structure and two child structures ResponseA and ResponseB. I wrote "UnmarshalJson" function for ParentA structure. The parentB structure and string field are not parsing.
How can I write the custom Unmarshal which only parse the specified structure/

  1. type ResponseA struct {
  2. PageA int `json:"pageA"`
  3. EntriesA []string `json:"entriesA"`
  4. }
  5. type ResponseB struct {
  6. PageB int `json:"pageB"`
  7. EntriesB []string `json:"entriesB"`
  8. }
  9. type ResponseParent struct {
  10. ResponseA
  11. ResponseB
  12. PageC int `json:"pageC"`
  13. }
  14. func (r *ResponseA) UnmarshalJSON(data []byte) error {
  15. // UnMarshal ResponseA structure
  16. }
  17. func main() {
  18. jsonStr := `{"pageA": 1, "entriesA": ["classA"], "pageB": 2, "entriesB":
  19. ["classC","classD"], "pageC":3}`
  20. // str := `{"page": 1, "entries": ["classA", "classB"]}`
  21. var res *ResponseParent
  22. json.Unmarshal([]byte(jsonStr), &res)
  23. entriesA := res.EntriesA
  24. pageA := res.PageA
  25. entriesB := res.EntriesB
  26. pageB := res.PageB
  27. pageC := res.PageC
  28. fmt.Println("========Response A==========a")
  29. fmt.Println("PageA: %v", pageA)
  30. fmt.Println("EntriesA: %v", entriesA)
  31. fmt.Println("========Response B==========a")
  32. fmt.Println("PageB: %v", pageB)
  33. fmt.Println("EntriesB: %v", entriesB)
  34. fmt.Println("PageC: %v", pageC)
  35. }
  36. OutPut:
  37. ========Response A==========a
  38. PageA: %v 1
  39. EntriesA: %v [classA]
  40. ========Response B==========a
  41. PageB: %v 0
  42. EntriesB: %v []
  43. PageC: %v 0

答案1

得分: 3

我测试了一下,我认为这是一个结构性问题,我不知道你是否可以更改你的 JSON 结构,但如果可以的话,你可以尝试只使用两个结构体来实现一个可扩展的结构。

  1. type Response struct {
  2. Page int `json:"page"`
  3. Entries []string `json:"entries"`
  4. }
  5. type GlobalResponse struct {
  6. ResponseA Response `json:"pageA"`
  7. ResponseB Response `json:"pageB"`
  8. ResponseC Response `json:"pageC"`
  9. }

然后可以这样访问它:

  1. var res *GlobalResponse
  2. json.Unmarshal([]byte(jsonStr), &res)
  3. entriesA := res.ResponseA.Entries
  4. pageA := res.ResponseA.Page
  5. // 对于每个页面都是如此...

最后,JSON 必须更改为以下结构:

  1. {
  2. "pageA":{
  3. "page":1,
  4. "entries":[
  5. "classA"
  6. ]
  7. },
  8. "pageB":{
  9. "page":2,
  10. "entries":[
  11. "classC",
  12. "classD"
  13. ]
  14. },
  15. "pageC":{
  16. "page":3
  17. }
  18. }

希望对你有所帮助。

英文:

I tested it and I think it's a structural issue, I don't know if you can change your json structure, but if yes you can try to use only 2 structs, to have an evolutive structure

  1. type Response struct {
  2. Page int `json:"page"`
  3. Entries []string `json:"entries"`}
  4. }
  5. type GlobalResponse struct {
  6. ResponseA Response `json:"pageA"`
  7. ResponseB Response `json:"pageB"`
  8. ResponseC Response `json:"pageC"`
  9. }

Then acces it this way :

  1. var res *GlobalResponse
  2. json.Unmarshal([]byte(jsonStr), &res)
  3. entriesA := res.ResponseA.Entries
  4. pageA := res.ResponseA.Page
  5. // Etc for each page...

Finally, the json must be changed to that structure

  1. {
  2. "pageA":{
  3. "page":1,
  4. "entries":[
  5. "classA"
  6. ]
  7. },
  8. "pageB":{
  9. "page":2,
  10. "entries":[
  11. "classC",
  12. "classD"
  13. ]
  14. },
  15. "pageC":{
  16. "page":3
  17. }
  18. }

Hope it helped

huangapple
  • 本文由 发表于 2023年4月6日 16:33:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/75947403.html
匿名

发表评论

匿名网友

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

确定