简体   繁体   中英

How to get structure specified in XML with Go?

I have an XML file like this test.xml

<metalib tagsetversion="1" name="TLog" version="1">
  <struct name="STRUCT_1">
    <entry name="ENTRY_1"/>
  </struct>

  <struct name="STRUCT_2">
    <entry name="ENTRY_1"/>
    <entry name="ENTRY_2"/>
  </struct>

   <!-- many structs -->

  <union name="UNION" version="1">
    <entry type="STRUCT_1"       id="ID_STRUCT_1" />
    <entry type="STRUCT_2"       id="ID_STRUCT_2" />
  </union>
</metalib>

And I want parse it to go struct like this:

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

and another map:

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

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

package main

import (
    "encoding/json"
    "os"
    "fmt"
    "testing"

    "github.com/clbanning/mxj/x2j"
)

func TestXml2Map(t *testing.T) {
    filePath := "test.xml"
    fi, fierr := os.Stat(filePath)
    if fierr != nil {
        fmt.Println("fierr:", fierr.Error())
        return
    }
    fh, fherr := os.Open(filePath)
    if fherr != nil {
        fmt.Println("fherr:", fherr.Error())
        return
    }
    defer fh.Close()
    buf := make([]byte, fi.Size())
    _, nerr := fh.Read(buf)
    if nerr != nil {
        fmt.Println("nerr:", nerr.Error())
        return
    }
    mmap, merr := x2j.XmlToMap(buf)
    if merr != nil {
        fmt.Println("merr:", merr.Error())
        return
    }
    // fmt.Println("mmap:", mmap)
    metalib := mmap["metalib"]
    // fmt.Println("metalib:", metalib)

    json.Unmarshal(buf, &metalib)
    mapmetalib := metalib.(map[string]interface{})
    // fmt.Println("mapmetalib struct: ", mapmetalib["struct"])

    istruct := mapmetalib["struct"]
    json.Unmarshal(buf, &istruct)
    mapstruct := istruct.([]interface{})
    fmt.Println("mapstruct: ", mapstruct)
}

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

package main

import (
    "encoding/xml"
    "fmt"
)

type entry struct {
    Name string `xml:"name,attr"`
}
type Struct struct {
    Name  string  `xml:"name,attr"`
    Entry []entry `xml:"entry"`
}
type metalib struct {
    XMLName xml.Name `xml:"metalib"`
    Struct  []Struct `xml:"struct"`
}

func main() {
    datastr := []byte(`<metalib tagsetversion="1" name="TLog" version="1">
        <struct name="STRUCT_1">
            <entry name="ENTRY_1"/>
        </struct>

        <struct name="STRUCT_2">
            <entry name="ENTRY_1"/>
            <entry name="ENTRY_2"/>
        </struct>

        <!-- many structs -->

        <union name="UNION" version="1">
        <entry type="STRUCT_1"       id="ID_STRUCT_1" />
        <entry type="STRUCT_2"       id="ID_STRUCT_2" />
        </union>
        </metalib>`)
    metalib := metalib{}
    err := xml.Unmarshal(datastr, &metalib)
    if err != nil {
        return
    }
    fmt.Printf("%v\n", metalib)

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM