0

encoding/xml.Decoder を使用して、http: //www.khronos.org/files/collada_schema_1_4 からロードされた XML ファイルを手動で解析しようとしています

テスト目的で、遭遇したトークンの種類を出力するドキュメントを繰り返し処理しています。

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) }
        }
    }
}

出力は次のとおりです。

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

最後の (24 行目) 行までに、多くの属性がルートのxs:schema要素とxs:importおよびxs:element要素の両方で渡されているにもかかわらず、ATTR または *ATTR 行が出力されないことに注意してください。

これは、Windows 7 64 ビットの Go 1.0.3 64 ビットにあります。何か間違ったことをしていますか、それとも Go パッケージのバグ レポートを提出する必要がありますか?

[補足: 通常のxml.Unmarshalを適切に準備された構造体に実行すると、既知の名前とマップされた属性がキャプチャされ、xml パッケージによって適切にマップされます。しかし、ルート要素で「不明な」属性も収集する必要があります(このユースケースの名前空間情報を収集するには、ユースケースはhttp://github.com/metaleap/go-xsdです)。Decoder.Token() . ]

4

1 に答える 1

5

はい、この動作は予想されます。属性は解析されますが、xml.Tokenとして返されません。属性は単にトークンではありません。参照: http: //golang.org/pkg/encoding/xml/#Token

属性には、TokenStartElementのAttrフィールドからアクセスできます。参照: http: //golang.org/pkg/encoding/xml/#StartElement

((いくつかの一般的なヒント:

a)printまたはprintlnを使用しないでください。

b)a、ok:= t。(SomeType)イディオマは「commaok」と呼ばれます。これは、ブール値が通常「is」ではなく「ok」という名前であるためです。これらの規則を守ってください。

c)慣用句は次のようになります

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

「ifa、is = t。(xml.Attr)...」のリストの代わりに

d)この「varsexml.StartElement」はすべてノイズ(クラッター)です。使用する

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

これにより、コードが読みやすくなります。))

于 2012-11-07T09:51:25.037 に答える