如何使用Go获取XML中指定的结构?

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

How to get structure specified in XML with Go?

问题

我有一个名为test.xml的XML文件,内容如下:

  1. <metalib tagsetversion="1" name="TLog" version="1">
  2. <struct name="STRUCT_1">
  3. <entry name="ENTRY_1"/>
  4. </struct>
  5. <struct name="STRUCT_2">
  6. <entry name="ENTRY_1"/>
  7. <entry name="ENTRY_2"/>
  8. </struct>
  9. <!-- 其他结构体 -->
  10. <union name="UNION" version="1">
  11. <entry type="STRUCT_1" id="ID_STRUCT_1" />
  12. <entry type="STRUCT_2" id="ID_STRUCT_2" />
  13. </union>
  14. </metalib>

我想要将其解析为以下结构体:

map["STRUCT_1"] == ["ENTRY_1"],map["STRUCT_2"] == ["ENTRY_1","ENTRY_2"]

还有另一个映射:

map2["ID_STRUCT_1"] == "STRUCT_1",map2["ID_STRUCT_2"] == "STRUCT_2"

我尝试使用github.com/clbanning/mxj/x2j来解决这个问题,我的代码如下:

  1. package main
  2. import (
  3. "encoding/json"
  4. "os"
  5. "fmt"
  6. "testing"
  7. "github.com/clbanning/mxj/x2j"
  8. )
  9. func TestXml2Map(t *testing.T) {
  10. filePath := "test.xml"
  11. fi, fierr := os.Stat(filePath)
  12. if fierr != nil {
  13. fmt.Println("fierr:", fierr.Error())
  14. return
  15. }
  16. fh, fherr := os.Open(filePath)
  17. if fherr != nil {
  18. fmt.Println("fherr:", fherr.Error())
  19. return
  20. }
  21. defer fh.Close()
  22. buf := make([]byte, fi.Size())
  23. _, nerr := fh.Read(buf)
  24. if nerr != nil {
  25. fmt.Println("nerr:", nerr.Error())
  26. return
  27. }
  28. mmap, merr := x2j.XmlToMap(buf)
  29. if merr != nil {
  30. fmt.Println("merr:", merr.Error())
  31. return
  32. }
  33. // fmt.Println("mmap:", mmap)
  34. metalib := mmap["metalib"]
  35. // fmt.Println("metalib:", metalib)
  36. json.Unmarshal(buf, &metalib)
  37. mapmetalib := metalib.(map[string]interface{})
  38. // fmt.Println("mapmetalib struct: ", mapmetalib["struct"])
  39. istruct := mapmetalib["struct"]
  40. json.Unmarshal(buf, &istruct)
  41. mapstruct := istruct.([]interface{})
  42. fmt.Println("mapstruct: ", mapstruct)
  43. }

但我感到困惑,不知道下一步该怎么做。

英文:

I have an XML file like this test.xml

  1. &lt;metalib tagsetversion=&quot;1&quot; name=&quot;TLog&quot; version=&quot;1&quot;&gt;
  2. &lt;struct name=&quot;STRUCT_1&quot;&gt;
  3. &lt;entry name=&quot;ENTRY_1&quot;/&gt;
  4. &lt;/struct&gt;
  5. &lt;struct name=&quot;STRUCT_2&quot;&gt;
  6. &lt;entry name=&quot;ENTRY_1&quot;/&gt;
  7. &lt;entry name=&quot;ENTRY_2&quot;/&gt;
  8. &lt;/struct&gt;
  9. &lt;!-- many structs --&gt;
  10. &lt;union name=&quot;UNION&quot; version=&quot;1&quot;&gt;
  11. &lt;entry type=&quot;STRUCT_1&quot; id=&quot;ID_STRUCT_1&quot; /&gt;
  12. &lt;entry type=&quot;STRUCT_2&quot; id=&quot;ID_STRUCT_2&quot; /&gt;
  13. &lt;/union&gt;
  14. &lt;/metalib&gt;

And I want parse it to go struct like this:

map[&quot;STRUCT_1&quot;] == [&quot;ENTRY_1&quot;], map[&quot;STRUCT_2&quot;] == [&quot;ENTRY_1&quot;,&quot;ENTRY_2&quot;]

and another map:

map2[&quot;ID_STRUCT_1&quot;] == &quot;STRUCT_1&quot;, map2[&quot;ID_STRUCT_2&quot;] == &quot;STRUCT_2&quot;

I have tried to use github.com/clbanning/mxj/x2j slove this problem, and my code like this:

  1. package main
  2. import (
  3. &quot;encoding/json&quot;
  4. &quot;os&quot;
  5. &quot;fmt&quot;
  6. &quot;testing&quot;
  7. &quot;github.com/clbanning/mxj/x2j&quot;
  8. )
  9. func TestXml2Map(t *testing.T) {
  10. filePath := &quot;test.xml&quot;
  11. fi, fierr := os.Stat(filePath)
  12. if fierr != nil {
  13. fmt.Println(&quot;fierr:&quot;, fierr.Error())
  14. return
  15. }
  16. fh, fherr := os.Open(filePath)
  17. if fherr != nil {
  18. fmt.Println(&quot;fherr:&quot;, fherr.Error())
  19. return
  20. }
  21. defer fh.Close()
  22. buf := make([]byte, fi.Size())
  23. _, nerr := fh.Read(buf)
  24. if nerr != nil {
  25. fmt.Println(&quot;nerr:&quot;, nerr.Error())
  26. return
  27. }
  28. mmap, merr := x2j.XmlToMap(buf)
  29. if merr != nil {
  30. fmt.Println(&quot;merr:&quot;, merr.Error())
  31. return
  32. }
  33. // fmt.Println(&quot;mmap:&quot;, mmap)
  34. metalib := mmap[&quot;metalib&quot;]
  35. // fmt.Println(&quot;metalib:&quot;, metalib)
  36. json.Unmarshal(buf, &amp;metalib)
  37. mapmetalib := metalib.(map[string]interface{})
  38. // fmt.Println(&quot;mapmetalib struct: &quot;, mapmetalib[&quot;struct&quot;])
  39. istruct := mapmetalib[&quot;struct&quot;]
  40. json.Unmarshal(buf, &amp;istruct)
  41. mapstruct := istruct.([]interface{})
  42. fmt.Println(&quot;mapstruct: &quot;, mapstruct)
  43. }

But I am confused and don't know how to do next step.

答案1

得分: 1

  1. package main
  2. import (
  3. "encoding/xml"
  4. "fmt"
  5. )
  6. type entry struct {
  7. Name string `xml:"name,attr"`
  8. }
  9. type Struct struct {
  10. Name string `xml:"name,attr"`
  11. Entry []entry `xml:"entry"`
  12. }
  13. type metalib struct {
  14. XMLName xml.Name `xml:"metalib"`
  15. Struct []Struct `xml:"struct"`
  16. }
  17. func main() {
  18. datastr := []byte(`<metalib tagsetversion="1" name="TLog" version="1">
  19. <struct name="STRUCT_1">
  20. <entry name="ENTRY_1"/>
  21. </struct>
  22. <struct name="STRUCT_2">
  23. <entry name="ENTRY_1"/>
  24. <entry name="ENTRY_2"/>
  25. </struct>
  26. <!-- many structs -->
  27. <union name="UNION" version="1">
  28. <entry type="STRUCT_1" id="ID_STRUCT_1" />
  29. <entry type="STRUCT_2" id="ID_STRUCT_2" />
  30. </union>
  31. </metalib>`)
  32. metalib := metalib{}
  33. err := xml.Unmarshal(datastr, &metalib)
  34. if err != nil {
  35. return
  36. }
  37. fmt.Printf("%v\n", metalib)
  38. }
英文:
  1. package main
  2. import (
  3. &quot;encoding/xml&quot;
  4. &quot;fmt&quot;
  5. )
  6. type entry struct {
  7. Name string `xml:&quot;name,attr&quot;`
  8. }
  9. type Struct struct {
  10. Name string `xml:&quot;name,attr&quot;`
  11. Entry []entry `xml:&quot;entry&quot;`
  12. }
  13. type metalib struct {
  14. XMLName xml.Name `xml:&quot;metalib&quot;`
  15. Struct []Struct `xml:&quot;struct&quot;`
  16. }
  17. func main() {
  18. datastr := []byte(`&lt;metalib tagsetversion=&quot;1&quot; name=&quot;TLog&quot; version=&quot;1&quot;&gt;
  19. &lt;struct name=&quot;STRUCT_1&quot;&gt;
  20. &lt;entry name=&quot;ENTRY_1&quot;/&gt;
  21. &lt;/struct&gt;
  22. &lt;struct name=&quot;STRUCT_2&quot;&gt;
  23. &lt;entry name=&quot;ENTRY_1&quot;/&gt;
  24. &lt;entry name=&quot;ENTRY_2&quot;/&gt;
  25. &lt;/struct&gt;
  26. &lt;!-- many structs --&gt;
  27. &lt;union name=&quot;UNION&quot; version=&quot;1&quot;&gt;
  28. &lt;entry type=&quot;STRUCT_1&quot; id=&quot;ID_STRUCT_1&quot; /&gt;
  29. &lt;entry type=&quot;STRUCT_2&quot; id=&quot;ID_STRUCT_2&quot; /&gt;
  30. &lt;/union&gt;
  31. &lt;/metalib&gt;`)
  32. metalib := metalib{}
  33. err := xml.Unmarshal(datastr, &amp;metalib)
  34. if err != nil {
  35. return
  36. }
  37. fmt.Printf(&quot;%v\n&quot;, metalib)
  38. }

huangapple
  • 本文由 发表于 2022年8月9日 19:05:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/73290795.html
匿名

发表评论

匿名网友

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

确定