英文:
How to get structure specified in XML with Go?
问题
我有一个名为test.xml的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>
   <!-- 其他结构体 -->
  <union name="UNION" version="1">
    <entry type="STRUCT_1"       id="ID_STRUCT_1" />
    <entry type="STRUCT_2"       id="ID_STRUCT_2" />
  </union>
</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来解决这个问题,我的代码如下:
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)
}
但我感到困惑,不知道下一步该怎么做。
英文:
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.
答案1
得分: 1
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)
}
英文:
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)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论