我可以将Go的xml.Unmarshall用于有序多态类型吗?

我可以将Go的xml.Unmarshall用于有序多态类型吗?,第1张

我可以将Go的xml.Unmarshall用于有序多态类型吗?

encoding/json
包不同,您没有
Unmarshaller
接口。在您的情况下,您将必须使用
Deprer
自己建议的。

下面是一个可行的解决方案:

package mainimport (    "bytes"    "encoding/xml"    "fmt")// An interface required by any instructiontype Executer interface {    Execute() error}var factoryMap map[string]func() Executer = make(map[string]func() Executer)type Play struct {    Loops int `xml:"loops,attr"`    File  string `xml:",innerxml"`    // Body of element is file name}func (p *Play) Execute() error {    for i := 0; i < p.Loops; i++ {        fmt.Println(`o/ ` + p.File)    }    return nil}type Say struct {    Voice string `xml:",innerxml"`}func (s *Say) Execute() error {    fmt.Println(s.Voice)    return nil}// Let's register the different instructions// You can have each Instruction struct in separate files, letting each file having an initfunc init() {    factoryMap["Play"] = func() Executer { return new(Play) }    factoryMap["Say"] = func() Executer { return new(Say) }}func Unmarshal(b []byte) ([]Executer, error) {    d := xml.NewDeprer(bytes.NewReader(b))    var actions []Executer    // Finding the first Root tag    for {        v, err := d.Token()        if err != nil { return nil, err        }        if _, ok := v.(xml.StartElement); ok { break        }    }    // Looping through the rest of the tokens    // finding the start of each.    for {        v, err := d.Token()        if err != nil { return nil, err        }        switch t := v.(type) {        case xml.StartElement: // We found a start of an instruction. // Let's check the name in our factoryMap // You should check that the Instruction name actually exists. Now it panics. f := factoryMap[t.Name.Local] instr := f() // We depre the rest of the tag into the instruction struct err := d.DepreElement(instr, &t) if err != nil {     return nil, err } // Appending the populated action actions = append(actions, instr)        case xml.EndElement: // We found the end tag of the Root. We are done! return actions, nil        }    }    return nil, nil}func main() {    xml := []byte(`<Root>    <Say>Playing file</Say>    <Play loops="2">https://host/somefile.mp3</Play>    <Say>Done playing</Say></Root>`)    actions, err := Unmarshal(xml)    if err != nil {        panic(err)    }    for _, instruction := range actions {        err = instruction.Execute()        if err != nil { fmt.Println(err)        }    }}

输出:

Playing file  o/ https://host/somefile.mp3  o/ https://host/somefile.mp3  Done playing

*** 场

当然,此代码并不完整,但是足以让您清楚地了解如何解决问题。



欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zaji/5427881.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-12-11
下一篇2022-12-11

发表评论

登录后才能评论

评论列表(0条)

    保存