英文:
How do I unmarshal nested XML elements into an array?
问题
我的XML包含一个预定义元素的数组,但我无法获取该数组。以下是XML的结构:
var xml_data = `<Parent>
                   <Val>Hello</Val>
                   <Children>
                       <Child><Val>Hello</Val></Child>
                       <Child><Val>Hello</Val></Child>
                       <Child><Val>Hello</Val></Child>
                   </Children>
               </Parent>`
这是完整的代码,这是playground链接。运行此代码将获取Parent.Val,但不会获取Parent.Children。
package main
import (
    "fmt"
    "encoding/xml"
)
func main() {
    container := Parent{}
    err := xml.Unmarshal([]byte(xml_data), &container)
    if err != nil {
        fmt.Println(err)
    } else {
        fmt.Println(container)    
    }
}
var xml_data = `<Parent>
                   <Val>Hello</Val>
                   <Children>
                       <Child><Val>Hello</Val></Child>
                       <Child><Val>Hello</Val></Child>
                       <Child><Val>Hello</Val></Child>
                   </Children>
               </Parent>`
type Parent struct {
    Val string
    Children []Child
}
type Child struct {
    Val string
}
我简化了问题在这里。基本上,我无法解组任何数组,不仅仅是预定义结构的数组。以下是更新后的工作代码。在该示例中,只有一个项目出现在容器接口中。
func main() {
    container := []Child{}
    err := xml.Unmarshal([]byte(xml_data), &container)
    if err != nil {
        fmt.Println(err)
    } else {
        fmt.Println(container)    
    }
    /* 
        只有一个Child项被获取
    */
}
var xml_data = `
                <Child><Val>Hello</Val></Child>
                <Child><Val>Hello</Val></Child>
                <Child><Val>Hello</Val></Child>
            `
type Child struct {
    Val string
}
英文:
My XML contains an array of predefined elements, but I can't pick up the array. Here is the XML structure:
var xml_data = `<Parent>
		           <Val>Hello</Val>
			       <Children>
				      <Child><Val>Hello</Val></Child>
				      <Child><Val>Hello</Val></Child>
				      <Child><Val>Hello</Val></Child>
		           </Children>
	            </Parent>`
Here is the full code and here is the playground link. Running this will pick up Parent.Val, but not Parent.Children.
package main
import (
	"fmt"
	"encoding/xml"
)
func main() {
	container := Parent{}
	err := xml.Unmarshal([]byte(xml_data), &container)
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println(container)	
	}
}
var xml_data = `<Parent>
		           <Val>Hello</Val>
			       <Children>
				      <Child><Val>Hello</Val></Child>
				      <Child><Val>Hello</Val></Child>
				      <Child><Val>Hello</Val></Child>
		           </Children>
	            </Parent>`
type Parent struct {
	Val string
	Children []Child
}
type Child struct {
	Val string
}
EDIT: I simplified the problem a bit here. Basically I can't unmarshal any array, not just of predefined structure. Below is the updated work code. In that example, only one item ends up in the container interface.
func main() {
	container := []Child{}
	err := xml.Unmarshal([]byte(xml_data), &container)
	if err != nil {
    	fmt.Println(err)
    } else {
    	fmt.Println(container)	
    }
	/* 
		ONLY ONE CHILD ITEM GETS PICKED UP
    */
}
var xml_data = `
	    	<Child><Val>Hello</Val></Child>
    		<Child><Val>Hello</Val></Child>
    		<Child><Val>Hello</Val></Child>
    	`
type Child struct {
	Val string
}
答案1
得分: 33
类型 Parent 结构体 {
Val 字符串
Children []Child xml:"Children>Child"  //只需使用 '>'
}
英文:
type Parent struct {
    Val string
    Children []Child  `xml:"Children>Child"`  //Just use the '>'
}
答案2
得分: 7
对于这种嵌套,你还需要为Children元素创建一个结构体:
package main
import (
	"fmt"
	"encoding/xml"
)
func main() {
	container := Parent{}
	err := xml.Unmarshal([]byte(xml_data), &container)
	
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println(container)	
	}
}
var xml_data = `<Parent>
			<Val>Hello</Val>
			<Children>
				<Child><Val>Hello</Val></Child>
				<Child><Val>Hello</Val></Child>
				<Child><Val>Hello</Val></Child>
			</Children>
		</Parent>`
type Parent struct {
	Val string
	Children Children
}
type Children struct {
	Child []Child
}
type Child struct {
	Val string
}
也可以在这里查看:Go Playground
请注意,如果使用以下XML结构,你的代码将可以工作(在将变量名从Children更改为Child后):
<Parent>
    <Val>Hello</Val>
    <Child><Val>Hello</Val></Child>
    <Child><Val>Hello</Val></Child>
    <Child><Val>Hello</Val></Child>
</Parent>
英文:
For this kind of nesting, you'll need also a struct for Children element:
package main
import (
	"fmt"
	"encoding/xml"
)
func main() {
	container := Parent{}
	err := xml.Unmarshal([]byte(xml_data), &container)
	
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println(container)	
	}
}
var xml_data = `<Parent>
			<Val>Hello</Val>
			<Children>
				<Child><Val>Hello</Val></Child>
				<Child><Val>Hello</Val></Child>
				<Child><Val>Hello</Val></Child>
			</Children>
		</Parent>`
type Parent struct {
	Val string
	Children Children
}
type Children struct {
	Child []Child
}
type Child struct {
	Val string
}
Also pasted here: Go Playground
Note that your code would work (after changing variable name from Children to Child) with this kind of XML structure:
<Parent>
    <Val>Hello</Val>
    <Child><Val>Hello</Val></Child>
    <Child><Val>Hello</Val></Child>
    <Child><Val>Hello</Val></Child>
</Parent>
1: https://play.golang.org/p/-rNryBSq01 "Go Playground"
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论