简体   繁体   English

使用Go将XML解码为接口类型?

[英]Decode XML into interface type with Go?

Is it possible to decode XML into an interface type with Go 1.3? Go 1.3是否可以将XML解码为接口类型?

For example, if the structs look something like this (simplified): 例如,如果结构看起来像这样(简化):

type Field interface { ... }

// DataField and ControlField satisfy Field interface
type DataField struct { ... } // <- One concrete type, with XML tags
type ControlField struct { ... } // <- Another concrete type, with XML tags


type Record struct {
    Fields []Field // <- Field is an interface
}

...
// we want to decode into a record, e.g.
var record Record
decoder.DecodeElement(&record, &se)
...

As far as I can see, it is possible to decode XML with the concrete types, eg: 据我所知,可以使用具体类型对XML进行解码,例如:

type Record struct {
    ControlFields []ControlField // <- Using concrete type works
    DataFields []DataField // <- Using concrete type works
}

But the interface type fails, although the implementations are annotated with the correct XML tags. 但是,接口类型会失败,尽管使用正确的XML标记对实现进行了注释。

For a runnable example, see http://play.golang.org/p/tPlw4Y74tt or as gist . 有关可运行的示例,请参见http://play.golang.org/p/tPlw4Y74ttgist

From looking at the code in the encoding/xml package, it seems, interface types are just skipped: 通过查看encoding/xml包中的代码 ,似乎只是跳过了接口类型:

...

switch v := val; v.Kind() {

case reflect.Interface:
    // TODO: For now, simply ignore the field. In the near
    //       future we may choose to unmarshal the start
    //       element on it, if not nil.
    return p.Skip()

...

Go version: 1.3. Go版本:1.3。

You need to initialize the values inside your interface arrays with some concrete type or xml will not be able to infer to which type are you referring to: 您需要使用某些具体类型来初始化接口数组中的值,否则xml将无法推断您所指的类型:

http://play.golang.org/p/6LVgK7rza9 http://play.golang.org/p/6LVgK7rza9

            // InterfaceRecord fails
            record := InterfaceRecord{
                Fields: []Field{&DataField{}},
            }

            decoder.DecodeElement(&record, &se)
            output, err := xml.MarshalIndent(record, "  ", "    ")
            if err != nil {
                fmt.Printf("error: %v\n", err)
            }

            os.Stdout.Write(output)

Output: 输出:

  <record>
      <d tag=""></d>
  </record>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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