dongxi1320 2012-11-07 08:49
浏览 87
已采纳

为什么Go的encoding / xml.Decoder.Token()不会像应有的那样生成xml.Attr令牌?

Using encoding/xml.Decoder I'm attempting to manually parse an XML file loaded from http://www.khronos.org/files/collada_schema_1_4

For test purposes, I'm just iterating over the document printing out whatever token type is encountered:

func Test (r io.Reader) {
    var t xml.Token
    var pa *xml.Attr
    var a xml.Attr
    var co xml.Comment
    var cd xml.CharData
    var se xml.StartElement
    var pi xml.ProcInst
    var ee xml.EndElement
    var is bool
    var xd = xml.NewDecoder(r)
    for i := 0; i < 24; i++ {
        if t, err = xd.Token(); (err == nil) && (t != nil) {
            if a, is = t.(xml.Attr); is { print("ATTR\t"); println(a.Name.Local) }
            if pa, is = t.(*xml.Attr); is { print("*ATTR\t"); println(pa) }
            if co, is = t.(xml.Comment); is { print("COMNT\t"); println(co) }
            if cd, is = t.(xml.CharData); is { print("CDATA\t"); println(cd) }
            if pi, is = t.(xml.ProcInst); is { print("PROCI\t"); println(pi.Target) }
            if se, is = t.(xml.StartElement); is { print("START\t"); println(se.Name.Local) }
            if ee, is = t.(xml.EndElement); is { print("END\t\t"); println(ee.Name.Local) }
        }
    }
}

Now here's the output:

PROCI   xml
CDATA   [1/64]0xf84004e050
START   schema
CDATA   [2/129]0xf84004d090
COMNT   [29/129]0xf84004d090
CDATA   [2/129]0xf84004d090
START   annotation
CDATA   [3/129]0xf84004d090
START   documentation
CDATA   [641/1039]0xf840061000
END     documentation
CDATA   [2/1039]0xf840061000
END     annotation
CDATA   [2/1039]0xf840061000
COMNT   [37/1039]0xf840061000
CDATA   [2/1039]0xf840061000
START   import
END     import
CDATA   [2/1039]0xf840061000
COMNT   [14/1039]0xf840061000
CDATA   [2/1039]0xf840061000
START   element
CDATA   [3/1039]0xf840061000
START   annotation

Notice no ATTR or *ATTR lines are output even though by the last (24th) line many attributes have been passed both in the root xs:schema element as well as in xs:import and xs:element elements.

This is in Go 1.0.3 64-bit under Windows 7 64-bit. Am I doing something wrong or should I file a Go package bug report?

[Side note: when doing a normal xml.Unmarshal into properly prepared structs, known-named-and-mapped attributes are captured and mapped by the xml package just fine. But I also need to collect "unknown" attributes in the root element (to collect namespace information for this use-case, the use-case being http://github.com/metaleap/go-xsd ), hence my attempts to use Decoder.Token().]

  • 写回答

1条回答 默认 最新

  • drol55885602 2012-11-07 09:51
    关注

    Yes, this behavior is expected. The attributes are parsed, but not returned as a xml.Token. Attributes simply arn't Tokens. See: http://golang.org/pkg/encoding/xml/#Token

    The attributes are accessible through the Attr field in the Token StartElement. See: http://golang.org/pkg/encoding/xml/#StartElement

    (( Some general hints:

    a) Do not use print or println.

    b) The a, ok := t.(SomeType) idioma is called "comma okay", because the boolean is normaly named "ok", not "is". Please stick to these conventions.

    c) Idiomatic would be something like

    switch t := t.(type) {
      case xml.StartElement: ...
      case xml.EndElement: ...
    }
    

    instead of your list of "if a, is = t.(xml.Attr) ..."

    d) All this "var se xml.StartElement" is noise (clutter). Use

    if se, ok := t.(xml.StartElement); ok { ... }
    

    This would make your code much readable. ))

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 测距传感器数据手册i2c
  • ¥15 RPA正常跑,cmd输入cookies跑不出来
  • ¥15 求帮我调试一下freefem代码
  • ¥15 matlab代码解决,怎么运行
  • ¥15 R语言Rstudio突然无法启动
  • ¥15 关于#matlab#的问题:提取2个图像的变量作为另外一个图像像元的移动量,计算新的位置创建新的图像并提取第二个图像的变量到新的图像
  • ¥15 改算法,照着压缩包里边,参考其他代码封装的格式 写到main函数里
  • ¥15 用windows做服务的同志有吗
  • ¥60 求一个简单的网页(标签-安全|关键词-上传)
  • ¥35 lstm时间序列共享单车预测,loss值优化,参数优化算法