// An <xs:annotation> element may contain zero or more <xs:documentation> // children. The xsd package joins the content of these children, separated // with blank lines. func (doc *annotation) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { buf := make([][]byte, 1) var ( tok xml.Token err error ) Loop: for { tok, err = d.Token() if err != nil { break } switch tok := tok.(type) { case xml.EndElement: break Loop case xml.StartElement: if (tok.Name != xml.Name{schemaNS, "documentation"}) { if err := d.Skip(); err != nil { return err } } var frag []byte if err := d.DecodeElement(&frag, &tok); err != nil { return err } buf = append(buf, bytes.TrimSpace(frag)) } } *doc = annotation(bytes.TrimSpace(bytes.Join(buf, []byte("\n\n")))) return err }
// UnmarshalXML unmarshals UserData XML. func (u *UserData) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { // Assume that UserData has the same general key-value structure as // EventData does. in := struct { Pairs []KeyValue `xml:",any"` }{} // Read tokens until we find the first StartElement then unmarshal it. for { t, err := d.Token() if err != nil { return err } if se, ok := t.(xml.StartElement); ok { err = d.DecodeElement(&in, &se) if err != nil { return err } u.Name = se.Name u.Pairs = in.Pairs d.Skip() break } } return nil }
func (m *Map) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { var err error for _, attr := range start.Attr { if attr.Name.Local == "extent" { m.setBounds(attr.Value) } if attr.Name.Local == "bgcolor" { m.BgColor = color.Hex(attr.Value) } if attr.Name.Local == "srs" { m.Srs, _ = proj.NewProjection(attr.Value) } } if m.Srs == nil { m.Srs, err = proj.NewProjection(defaultSrsOut) if err != nil { fmt.Println(err.Error()) } } for { e, err := d.Token() if err != nil { return err } switch e := e.(type) { case xml.EndElement: if e.Name.Local == start.Name.Local { return nil } case xml.StartElement: switch e.Name.Local { case "Style": style := new(Style) if err := d.DecodeElement(style, &e); err != nil { return err } m.Styles = append(m.Styles, style) case "Layer": layer := new(Layer) if err := d.DecodeElement(layer, &e); err != nil { return err } m.Layers = append(m.Layers, layer) case "Include": var name string if err := d.DecodeElement(&name, &e); err != nil { return err } include, err := loadInclude(name) if err != nil { return err } m.Styles = append(m.Styles, include.Styles...) m.Layers = append(m.Layers, include.Layers...) } } } return d.Skip() }
func getCharData(decoder *xml.Decoder) string { t, err := decoder.Token() if err != nil { return "" } charData := string(t.(xml.CharData)) err = decoder.Skip() if err != nil { return "" } return charData }
func (context *Context) Handle(dec *xml.Decoder, token xml.Token) error { // should we just skip the token? if context.ShouldSkip(token) { dec.Skip() return nil } // should we inline something from somewhere else? if IsConref(token) { return context.HandleConref(dec, token.(xml.StartElement)) } startdepth := context.Encoder.Depth() defer func() { if startdepth != context.Encoder.Depth() { fmt.Println(context.Encoder.Stack()) panic("mismatched start and end tag in html output") } }() // should we unwrap the tag? if context.ShouldUnwrap(token) { return context.Recurse(dec) } // is it a starting token? if start, isStart := token.(xml.StartElement); isStart { // is it custom already before naming if process, isCustom := context.Rules.Custom[start.Name.Local]; isCustom { return process(context, dec, start) } // handle tag renaming if renaming, ok := context.Rules.Rename[start.Name.Local]; ok { // setAttr(&start, "data-dita", start.Name.Local) start.Name.Local = renaming.Name setAttr(&start, "class", renaming.AddClass) } // is it custom after renaming? if process, isCustom := context.Rules.Custom[start.Name.Local]; isCustom { return process(context, dec, start) } return context.EmitWithChildren(dec, start) } // otherwise, encode as is return context.Encoder.Encode(token) }
func parseRequest(d *xml.Decoder) (name string, args []interface{}, e error) { _, e = expectNextTag(d, "methodCall") if e != nil { return } _, e = expectNextTag(d, "methodName") if e != nil { return } var t xml.Token t, e = d.Token() if e != nil { return } data, ok := t.(xml.CharData) if !ok { e = errors.New("Invalid methodName") } name = string(data) _, e = expectNextTag(d, "params") if e != nil { return } for { t, e = d.Token() switch t.(type) { case xml.StartElement: elem, _ := t.(xml.StartElement) if elem.Name.Local == "value" { var x interface{} x, e = parseValue(d) if e != nil { return } args = append(args, x) } case xml.EndElement: elem, _ := t.(xml.EndElement) if elem.Name.Local == "params" { d.Skip() return } } } e = errors.New("Missing end element.") return }
// StringMap marshals into XML. func (this KV) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { // v := KV[start.Name] // if v != nil { // append(v) // } else { // // } if this == nil { this = map[string]interface{}{} } this[start.Attr[0].Value] = "int{1}" fmt.Println(this) d.Skip() return nil for t, err := d.Token(); err == nil; t, err = d.Token() { // fmt.Println(start.Attr[0].Value) switch t.(type) { default: } // fmt.Println(t) // switch token := t.(type) { // // 处理元素开始(标签) // case xml.StartElement: // name := token.Name.Local // fmt.Printf("Token name: %s\n", name) // for _, attr := range token.Attr { // attrName := attr.Name.Local // attrValue := attr.Value // fmt.Printf("An attribute is: %s %s\n", attrName, attrValue) // } // // 处理元素结束(标签) // case xml.EndElement: // fmt.Printf("Token of '%s' end\n", token.Name.Local) // // 处理字符数据(这里就是元素的文本) // case xml.CharData: // content := string([]byte(token)) // fmt.Printf("This is the content: %v\n", content) // default: // // ... // } } // start return nil }
// findToken consumes tokens in the given decoder until either the given // name is found, EOF, or the given end token is found. In the case of end // tokens the return is (nil, nil) func findToken(d *xml.Decoder, name, halt string) (*xml.StartElement, error) { for { tok, err := d.Token() if err != nil { return nil, err } if se, ok := tok.(xml.StartElement); ok { if se.Name.Local == name { return &se, nil } d.Skip() } if ee, ok := tok.(xml.EndElement); ok { if ee.Name.Local == halt { return nil, nil } } } }
// UnmarshalXML for parsing XML answer func (r *DirectLinkResponse) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { err := d.Skip() if err != nil { return err } if start.Name.Local != "ncresponse" { return nil } r.data = make(map[string]string, len(start.Attr)) for _, attr := range start.Attr { r.data[attr.Name.Local] = attr.Value } return nil }
func parseResponse(d *xml.Decoder) (ok bool, result interface{}, e error) { _, e = expectNextTag(d, "methodResponse") if e != nil { return } var se xml.StartElement se, e = nextTag(d) if e != nil { return } switch se.Name.Local { case "params": _, e = expectNextTag(d, "param") if e != nil { return } _, e = expectNextTag(d, "value") if e != nil { return } result, e = parseValue(d) if e != nil { return } ok = true d.Skip() d.Skip() d.Skip() d.Skip() return case "fault": _, e = expectNextTag(d, "value") if e != nil { return } result, e = parseValue(d) if e != nil { return } ok = false d.Skip() d.Skip() d.Skip() return } e = errors.New("Missing end element.") return }
// UnmarshalXML is needed to implement XMLUnmarshaler for custom, value-based // unmarshaling of relation-list elements. func (r *TargetRelationsMap) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { var targetType string for _, v := range start.Attr { if v.Name.Local == "target-type" { targetType = v.Value break } } if *r == nil { (*r) = make(map[string][]Relation) } switch targetType { case "artist": var res struct { XMLName xml.Name `xml:"relation-list"` Relations []*ArtistRelation `xml:"relation"` } if err := d.DecodeElement(&res, &start); err != nil { return err } (*r)[targetType] = make([]Relation, len(res.Relations)) for i, v := range res.Relations { (*r)[targetType][i] = v } case "release": var res struct { XMLName xml.Name `xml:"relation-list"` Relations []*ReleaseRelation `xml:"relation"` } if err := d.DecodeElement(&res, &start); err != nil { return err } (*r)[targetType] = make([]Relation, len(res.Relations)) for i, v := range res.Relations { (*r)[targetType][i] = v } case "url": var res struct { XMLName xml.Name `xml:"relation-list"` Relations []*URLRelation `xml:"relation"` } if err := d.DecodeElement(&res, &start); err != nil { return err } (*r)[targetType] = make([]Relation, len(res.Relations)) for i, v := range res.Relations { (*r)[targetType][i] = v } // FIXME implement missing relations default: return d.Skip() } return nil }
// Parse a value after the <value> tag has been read. On (non-error) // return, the </value> closing tag will have been read. func parseValue(d *xml.Decoder) (interface{}, error) { token, e := d.Token() // t, e := nextTag(d) if e != nil { return nil, e } switch t := token.(type) { case xml.StartElement: switch t.Name.Local { case "boolean": token, e := d.Token() if e != nil { return nil, e } data, ok := token.(xml.CharData) if !ok { return nil, errors.New("boolean: Not a CharData") } var i int64 i, e = strconv.ParseInt(string(data), 10, 4) if e != nil { return nil, e } switch i { case 0: d.Skip() // </bool> d.Skip() // </value> return false, nil case 1: d.Skip() // </bool> d.Skip() // </value> return true, nil default: return nil, errors.New("Parse error") } case "i4", "int": token, e := d.Token() if e != nil { return nil, e } data, ok := token.(xml.CharData) if !ok { return nil, errors.New("int: Not a CharData") } var i int64 i, e = strconv.ParseInt(string(data), 0, 32) if e != nil { return nil, e } d.Skip() // </i4> or </int> d.Skip() // </value> return int32(i), nil case "double": token, e := d.Token() if e != nil { return nil, e } data, ok := token.(xml.CharData) if !ok { return nil, errors.New("double: Not a CharData") } var f float64 f, e = strconv.ParseFloat(string(data), 64) if e != nil { return nil, e } d.Skip() // </double> d.Skip() // </value> return f, nil case "string": token, e := d.Token() if e != nil { return nil, e } data, ok := token.(xml.CharData) if ok { s := string(data.Copy()) d.Skip() // </string> d.Skip() // </value> return s, nil } else { var end xml.EndElement end, ok = token.(xml.EndElement) if ok && end.Name.Local == "string" { d.Skip() // </value> return "", nil } else { return nil, errors.New("string: parse error") } } case "dateTime.iso8601": return nil, errors.New("Not supported1") case "base64": token, e := d.Token() if e != nil { return nil, e } data, ok := token.(xml.CharData) if !ok { return nil, errors.New("base64: Not a CharData") } var bs []byte bs, e = base64.StdEncoding.DecodeString(string(data)) if e != nil { return nil, e } d.Skip() // </base64> d.Skip() // </value> return bs, nil case "array": _, e := expectNextTag(d, "data") if e != nil { return nil, e } var a []interface{} for { t, e := d.Token() if e != nil { return nil, e } switch t.(type) { case xml.StartElement: elem, _ := t.(xml.StartElement) if elem.Name.Local == "value" { var val interface{} val, e = parseValue(d) if e != nil { return nil, e } a = append(a, val) } case xml.EndElement: elem, _ := t.(xml.EndElement) if elem.Name.Local == "array" { d.Skip() // </value> return a, nil } } } case "struct": m := make(map[string]interface{}) var name string var value interface{} for { t, e := d.Token() if e != nil { return nil, e } switch t.(type) { case xml.StartElement: elem, _ := t.(xml.StartElement) switch elem.Name.Local { case "member": case "name": t, e = d.Token() if e != nil { return nil, e } data, ok := t.(xml.CharData) if ok { name = string(data) } else { return nil, errors.New("") } case "value": value, e = parseValue(d) if e != nil { return nil, e } } case xml.EndElement: elem, _ := t.(xml.EndElement) switch elem.Name.Local { case "member": m[name] = value case "struct": d.Skip() // </value> return m, nil } } } default: return nil, errors.New("Not supported: t.Name.Local = " + t.Name.Local) } case xml.CharData: copy := t.Copy() // spaces and newlines for pretty formatting of xml // show up as chardata, so here we ignore them. stripped := strings.TrimSpace(string(copy)) if stripped != "" { d.Skip() // </value> return string(copy), nil } else { return parseValue(d) } case xml.EndElement: return "", nil } return nil, errors.New("Invalid data type") }
func parseValue(d *xml.Decoder) (interface{}, error) { t, e := nextTag(d) if e != nil { return nil, e } switch t.Name.Local { case "boolean": token, e := d.Token() if e != nil { return nil, e } data, ok := token.(xml.CharData) if !ok { return nil, errors.New("boolean: Not a CharData") } var i int64 i, e = strconv.ParseInt(string(data), 10, 4) if e != nil { return nil, e } switch i { case 0: d.Skip() return false, nil case 1: d.Skip() return true, nil default: return nil, errors.New("Parse error") } case "i4", "int": token, e := d.Token() if e != nil { return nil, e } data, ok := token.(xml.CharData) if !ok { return nil, errors.New("int: Not a CharData") } var i int64 i, e = strconv.ParseInt(string(data), 0, 32) if e != nil { return nil, e } d.Skip() return int32(i), nil case "double": token, e := d.Token() if e != nil { return nil, e } data, ok := token.(xml.CharData) if !ok { return nil, errors.New("double: Not a CharData") } var f float64 f, e = strconv.ParseFloat(string(data), 64) if e != nil { return nil, e } d.Skip() return f, nil case "string": token, e := d.Token() if e != nil { return nil, e } data, ok := token.(xml.CharData) if ok { s := string(data.Copy()) d.Skip() return s, nil } else { var end xml.EndElement end, ok = token.(xml.EndElement) if ok && end.Name.Local == "string" { return "", nil } else { return nil, errors.New("string: parse error") } } case "dateTime.iso8601": return nil, errors.New("Not supported") case "base64": token, e := d.Token() if e != nil { return nil, e } data, ok := token.(xml.CharData) if !ok { return nil, errors.New("base64: Not a CharData") } var bs []byte bs, e = base64.StdEncoding.DecodeString(string(data)) if e != nil { return nil, e } d.Skip() return bs, nil case "array": _, e := expectNextTag(d, "data") if e != nil { return nil, e } var a []interface{} for { t, e := d.Token() if e != nil { return nil, e } switch t.(type) { case xml.StartElement: elem, _ := t.(xml.StartElement) if elem.Name.Local == "value" { var val interface{} val, e = parseValue(d) if e != nil { return nil, e } a = append(a, val) d.Skip() } case xml.EndElement: elem, _ := t.(xml.EndElement) if elem.Name.Local == "array" { return a, nil } } } return nil, errors.New("Not reached") case "struct": m := make(map[string]interface{}) var name string var value interface{} for { t, e := d.Token() if e != nil { return nil, e } switch t.(type) { case xml.StartElement: elem, _ := t.(xml.StartElement) switch elem.Name.Local { case "member": case "name": t, e = d.Token() if e != nil { return nil, e } data, ok := t.(xml.CharData) if ok { name = string(data) } else { return nil, errors.New("") } case "value": value, e = parseValue(d) if e != nil { return nil, e } } case xml.EndElement: elem, _ := t.(xml.EndElement) switch elem.Name.Local { case "member": m[name] = value case "struct": return m, nil } } } return nil, errors.New("Not reached") default: return nil, errors.New("Not supported") } return nil, errors.New("Invalid data type") }
func (context *Context) HandleConref(dec *xml.Decoder, start xml.StartElement) error { dec.Skip() conref, conkeyref, conrefend := getAttr(&start, "conref"), getAttr(&start, "conkeyref"), getAttr(&start, "conrefend") keyfile, keypath := context.ResolveKeyRef(conkeyref) startfile, startpath := SplitLink(conref) endfile, endpath := SplitLink(conrefend) // startfile and endfile are relative to current direcotry // keyfile is absolute relative to the root if startfile != "" { startfile = path.Join(path.Dir(context.DecodingPath), startfile) } if endfile != "" { endfile = path.Join(path.Dir(context.DecodingPath), endfile) } // conref is missing, try to use conkeyref instead if startfile == "" && keyfile != "" { if startpath != "" || endpath != "" { return errors.New("invalid conkeyref setup") } startfile, startpath = keyfile, keypath } // conrefend is missing, fallback to either conref or conkeyref if endfile == "" && endpath == "" { endfile, endpath = startfile, startpath } // start/end files are both missing, use the current file if startfile == "" && endfile == "" { startfile, endfile = context.DecodingPath, context.DecodingPath } // sanity check if startfile != endfile { return errors.New("conref and conrefend are in different files: " + startfile + " --> " + endfile) } if !SameRootElement(startpath, endpath) { return errors.New("conref and conrefend have different root elements: " + conref + " --> " + conrefend) } if startpath == "" || endpath == "" { return errors.New("invalid conref path: " + conref + " --> " + conrefend) } previousPath := context.DecodingPath defer func() { context.DecodingPath = previousPath }() data, _, err := context.Index.ReadFile(startfile) if err != nil { return fmt.Errorf("problem opening %v: %v", startfile, err) } subdec := xml.NewDecoder(bytes.NewReader(data)) subfirst, err := WalkNodePath(subdec, startpath) if err != nil { if err == io.EOF { return errors.New("did not find conref: " + conref) } return err } var subtoken xml.Token = subfirst endingid := path.Base(endpath) for { err := context.Handle(subdec, subtoken) if err != nil { return err } // is it ending? if substart, isStart := subtoken.(xml.StartElement); isStart { if strings.EqualFold(endingid, getAttr(&substart, "id")) { return nil } } if _, isEnd := subtoken.(xml.EndElement); isEnd { return errors.New("did not find conrefend: " + conrefend) } subtoken, err = subdec.Token() if err != nil { return err } } return nil }
func (s *XSDSchemaMeta) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { s.Attributes = start.Attr return d.Skip() }
func TODO(context *Context, dec *xml.Decoder, start xml.StartElement) error { context.Encoder.WriteRaw(`<div class="conversion-error">TODO ` + start.Name.Local + `</div>`) dec.Skip() return nil }