// UnmarshalXML function unmarshal an <album-list> XML fragment to a Map[string]*Album func (am *AlbumMap) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { // result m := map[string]*Album{} LOOP: for { token, err := d.Token() if err != nil { return err } switch t := token.(type) { case xml.StartElement: if t.Name.Local == "album" { a := Album{} elmt := xml.StartElement(t) d.DecodeElement(&a, &elmt) m[a.ID] = &a } case xml.EndElement: if t.Name.Local == "album-list" { break LOOP } } } *am = AlbumMap(m) return nil }
func parseProfileXML(profileName string, text string) Profile { p := new(Profile) p.name = profileName p.fieldPermissions = map[string]FLS{} p.objectPermissions = map[string]OLS{} var currentElement XLS r := strings.NewReader(text) parser := xml.NewDecoder(r) depth := 0 eltType := "" propertyName := "" for { token, err := parser.Token() if err != nil { break } switch t := token.(type) { case xml.StartElement: elmt := xml.StartElement(t) name := elmt.Name.Local if depth == 1 { eltType = name if eltType == "objectPermissions" { currentElement = new(OLS) } else if eltType == "fieldPermissions" { currentElement = new(FLS) } else { currentElement = nil } } if depth == 2 { propertyName = name } depth++ case xml.EndElement: if depth == 2 && currentElement != nil { currentElement.addToProfile(*p) } depth-- case xml.CharData: bytes := xml.CharData(t) if currentElement != nil && depth == 3 { currentElement.addProperty(propertyName, string(bytes)) } default: } } // fmt.Println(p) return *p }
// parseXMLtoTOML parses XML to TOML (in a slightly brain dead way). func parseXMLtoTOML(input []byte) { parser := xml.NewDecoder(bytes.NewReader(input)) keywords := []string{} name := "" fmt.Println("% # Quick 'n dirty translated by mmark") for { token, err := parser.Token() if err != nil { break } switch t := token.(type) { case xml.StartElement: elmt := xml.StartElement(t) name = elmt.Name.Local switch name { case "author": fmt.Println("%\n% [[author]]") outAttr(elmt.Attr) case "rfc": fallthrough case "title": outAttr(elmt.Attr) case "address": fmt.Println("% [author.address]") case "postal": fmt.Println("% [author.address.postal]") case "date": outDate(elmt.Attr) } case xml.CharData: if name == "" { continue } data := xml.CharData(t) data = bytes.TrimSpace(data) if len(data) == 0 { continue } if name == "keyword" { keywords = append(keywords, "\""+string(data)+"\"") continue } outString(name, string(data)) case xml.EndElement: name = "" case xml.Comment: // don't care case xml.ProcInst: // don't care case xml.Directive: // don't care default: } } outArray("keyword", keywords) }
// ReplaceAttribute replaces the attribute of the first node that matches the name func ReplaceAttributeIf(attrName, attrValue string, cond ConditionFunc) TransformFunc { return func(parents *NodeList, in xml.Token) []xml.Token { switch t := in.(type) { case xml.StartElement: if cond(parents, in) { e := xml.StartElement(t) return []xml.Token{SetAttribute(e, attrName, attrValue)} } } return []xml.Token{in} } }
func main() { if len(os.Args) != 2 { fmt.Println("Usage: ", os.Args[0], "file") os.Exit(1) } file := os.Args[1] bytes, err := ioutil.ReadFile(file) checkError(err) r := strings.NewReader(string(bytes)) parser := xml.NewDecoder(r) depth := 0 for { token, err := parser.Token() if err != nil { break } switch t := token.(type) { case xml.StartElement: elmt := xml.StartElement(t) name := elmt.Name.Local printElmt(name, depth) depth++ case xml.EndElement: depth-- elmt := xml.EndElement(t) name := elmt.Name.Local printElmt(name, depth) case xml.CharData: bytes := xml.CharData(t) printElmt("\""+string([]byte(bytes))+"\"", depth) case xml.Comment: printElmt("Comment", depth) case xml.ProcInst: printElmt("ProcInst", depth) case xml.Directive: printElmt("Directive", depth) default: fmt.Println("Unknown") } } }
// UnmarshalXML function unmarshal an <artist-list> XML fragment to a Map[string]*Artist func (am *Artists) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { /* https://groups.google.com/forum/#!topic/golang-nuts/Y6KitymP7Dg https://gist.github.com/chrisfarms/1377218 http://play.golang.org/p/v9Nt57Fj03 */ // Artists.Map m := map[string]*Artist{} LOOP: for { token, err := d.Token() if err != nil { return err } switch t := token.(type) { case xml.StartElement: if t.Name.Local == "artist" { a := Artist{} elmt := xml.StartElement(t) d.DecodeElement(&a, &elmt) m[a.ID] = &a } case xml.EndElement: if t.Name.Local == "artist-list" { break LOOP } } } // Artists.List l := make([]*Artist, len(m)) var j int for _, a := range m { l[j] = a j++ } sort.Sort(bySortName(l)) // result *am = Artists{Map: m, List: l} return nil }
func parseCustomObjectXML(objectName string, text string) CustomObject { obj := CustomObject{objectName: objectName, nbFields: 0, fieldNames: make([]string, 900, 900)} r := strings.NewReader(text) parser := xml.NewDecoder(r) depth := 0 var firstLevel, secondLevel string for { token, err := parser.Token() if err != nil { break } switch t := token.(type) { case xml.StartElement: elmt := xml.StartElement(t) name := elmt.Name.Local if depth == 1 { firstLevel = name } else if depth == 2 { secondLevel = name } depth++ case xml.EndElement: if depth == 3 { secondLevel = "" } else if depth == 2 { firstLevel = "" } depth-- case xml.CharData: bytes := xml.CharData(t) if depth == 3 && firstLevel == "fields" && secondLevel == "fullName" { obj.addField(string(bytes)) } default: } } // fmt.Println(obj) return obj }
// SerializeXMLWithQueries Serializes text into Query struct func SerializeXMLWithQueries(d *xml.Decoder, start xml.StartElement) ([]interface{}, error) { var queries []interface{} for { if token, err := d.Token(); (err == nil) && (token != nil) { switch t := token.(type) { case xml.StartElement: e := xml.StartElement(t) q := stringToQueryStruct(e.Name.Local) err = d.DecodeElement(q, &e) queries = append(queries, q) case xml.EndElement: e := xml.EndElement(t) if e.Name.Space == "http://marklogic.com/appservices/search" && e.Name.Local == "queries" { return queries, err } } } else { return queries, err } } }
// UnmarshalXML function unmarshal an <album-list> XML fragment to a Map[string]*Album func (ps *Playlists) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { // result m := map[string]*Playlist{} LOOP: for { token, err := d.Token() if err != nil { return err } switch t := token.(type) { case xml.StartElement: if t.Name.Local == "playlist" { p := Playlist{} elmt := xml.StartElement(t) d.DecodeElement(&p, &elmt) m[p.ID] = &p } case xml.EndElement: if t.Name.Local == "playlist-list" { break LOOP } } } // Playlists.List l := make([]*Playlist, len(m)) var j int for _, a := range m { l[j] = a j++ } sort.Sort(byID(l)) // result *ps = Playlists{Map: m, List: l} return nil }
//UnmarshalXML for Match struct in a special way to handle highlighting matching text func (m *Match) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { for i := range start.Attr { attr := start.Attr[i] if attr.Name.Local == "path" { m.Path = attr.Value break } } for { if token, err := d.Token(); (err == nil) && (token != nil) { switch t := token.(type) { case xml.StartElement: var content string e := xml.StartElement(t) d.DecodeElement(&content, &e) text := Text{ Text: content, HighlightedText: e.Name.Space == searchNamespace && e.Name.Local == "highlight", } m.Text = append(m.Text, text) case xml.EndElement: e := xml.EndElement(t) if e.Name.Space == searchNamespace && e.Name.Local == "match" { return nil } case xml.CharData: b := xml.CharData(t) text := Text{ Text: string([]byte(b)), HighlightedText: false, } m.Text = append(m.Text, text) } } else { return err } } }
func main() { input := ` <person> <name> <family> Newmarch </family> <personal> Jan </personal> </name> <email type="personal"> [email protected] </email> <email type="work"> [email protected] </email> </person> ` /* if len(os.Args) != 2 { fmt.Println("Usage: ", os.Args[0], "file") os.Exit(1) } file := os.Args[1] bytes, err := ioutil.ReadFile(file) checkError(err) r := strings.NewReader(string(bytes)) */ r := strings.NewReader(input) parser := xml.NewDecoder(r) depth := 0 for { token, err := parser.Token() if err != nil { break } switch t := token.(type) { case xml.StartElement: elmt := xml.StartElement(t) name := elmt.Name.Local printElmt(name, depth) depth++ case xml.EndElement: depth-- elmt := xml.EndElement(t) name := elmt.Name.Local printElmt(name, depth) case xml.CharData: bytes := xml.CharData(t) printElmt("\""+string([]byte(bytes))+"\"", depth) case xml.Comment: printElmt("Comment", depth) case xml.ProcInst: printElmt("ProcInst", depth) case xml.Directive: printElmt("Directive", depth) default: fmt.Println("Unknown") } } }
func parseSvg(svgData []byte) (*nodeDef, *gkerr.GkErrDef) { var currentNode *nodeDef = new(nodeDef) var gkErr *gkerr.GkErrDef var reader *bytes.Buffer = bytes.NewBuffer(svgData) var decoder *xml.Decoder decoder = xml.NewDecoder(reader) var currentCharData = make([]byte, 0, 0) for { var token xml.Token var err error token, err = decoder.Token() if err != nil { if err == io.EOF { break } gkErr = gkerr.GenGkErr("decoder.Token", err, ERROR_ID_SVG_PARSE) return nil, gkErr } switch token := token.(type) { case xml.StartElement: var startElement = xml.StartElement(token) if currentNode == nil { currentNode.childList = make([]*nodeDef, 0, 0) } var childNode *nodeDef = new(nodeDef) childNode.nameSpace = startElement.Name.Space childNode.nameLocal = startElement.Name.Local childNode.attributeList = make([]*attributeDef, 0, 0) childNode.charData = make([]byte, 0, 0) for _, attr := range startElement.Attr { var attribute *attributeDef = new(attributeDef) attribute.nameSpace = attr.Name.Space attribute.nameLocal = attr.Name.Local attribute.value = attr.Value childNode.attributeList = append(childNode.attributeList, attribute) } currentNode.childList = append(currentNode.childList, childNode) childNode.parentNode = currentNode currentNode = childNode // this forces charData to be only at the inner most xml level currentCharData = make([]byte, 0, 0) case xml.EndElement: currentNode.charData = currentCharData currentNode = currentNode.parentNode // this forces charData to be only at the inner most xml level currentCharData = make([]byte, 0, 0) case xml.CharData: var charData = xml.CharData(token) currentCharData = append(currentCharData, charData...) } } if (len(currentNode.childList) == 1) && (currentNode.childList[0].nameLocal == "svg") { return currentNode.childList[0], nil } return nil, gkerr.GenGkErr("invalid svg, no starting svg tag or multipe root nodes", nil, ERROR_ID_INVALID_SVG) }
func GelbooruGet(tags string) (Posts []Post, err error) { resp, err := http.Get("http://gelbooru.com/index.php?page=dapi&s=post&q=index&tags=" + strings.Replace(tags, " ", "+", -1)) if err != nil { return nil, err } defer resp.Body.Close() parser := xml.NewDecoder(resp.Body) //var token xml.Token entries := make([]Post, 0, 100) depth := 0 for { token, err := parser.Token() if err != nil { if err.Error() == "EOF" { break } else { return nil, err } } switch t := token.(type) { case xml.StartElement: elmt := xml.StartElement(t) //name := elmt.Name.Local if elmt.Name.Local == "post" { Post := new(Post) for i := 0; i < len(elmt.Attr); i++ { switch elmt.Attr[i].Name.Local { case "file_url": Post.File_url = elmt.Attr[i].Value break case "id": Post.Id = elmt.Attr[i].Value Post.Url = "http://gelbooru.com/index.php?page=post&s=view&id=" + Post.Id break case "tags": Post.Tags = elmt.Attr[i].Value } } entries = append(entries, *Post) } //printElmt(name, depth) depth++ case xml.EndElement: depth-- //elmt := xml.EndElement(t) //name := elmt.Name.Local //printElmt(name, depth) case xml.CharData: //bytes := xml.CharData(t) //printElmt("\"" + string([]byte(bytes)) + "\"", depth) case xml.Comment: //printElmt("Comment", depth) case xml.ProcInst: //printElmt("ProcInst", depth) case xml.Directive: //printElmt("Directive", depth) default: fmt.Println("Unknown") } } return entries, nil }
func parseGetPayloadList(body io.ReadCloser) (*PayloadList, error) { payloads := make(chan CompactData) parser := xml.NewDecoder(body) list := PayloadList{ Payloads: payloads, } delim := " " // backgroundable processing of the data into our buffer dataProcessing := func() { // this channel needs to be closed or the caller can infinite loop defer close(payloads) // this is the web socket that needs addressed defer body.Close() // extract the data for { token, err := parser.Token() if err != nil { list.Error = err break } switch t := token.(type) { case xml.StartElement: switch t.Name.Local { case "RETSPayloadList": mcd, err := ParseMetadataCompactDecoded(t, parser, delim) if err != nil { fmt.Println("failed to decode: ", err) list.Error = err return } payloads <- *mcd } } } } for { token, err := parser.Token() if err != nil { return nil, err } switch t := token.(type) { case xml.StartElement: elmt := xml.StartElement(t) switch elmt.Name.Local { case "RETS", "RETS-STATUS": rets, err := ParseRetsResponseTag(elmt) if err != nil { return nil, err } list.Rets = *rets go dataProcessing() return &list, nil case "DELIMITER": decoded, err := ParseDelimiterTag(elmt) if err != nil { return nil, err } delim = decoded } } } }