golang动态解析xml

/ go / 没有评论 / 1806浏览

golang动态解析xml

package main

import (
    "encoding/xml"
    "fmt"
    "mahonia"
    "os"
    "strconv"
    "text/template"
)

type Attribute struct {
    Name  string
    Value string
}

type Token struct {
    Name       string
    Attributes []Attribute
    Tokens     []Token
}

type Result struct {
    Root Token
}

var result = Result{}

func main() {

    if !parse("config.xml") {
        return
    }

    if !output("code_h.tpl", "code.h") {
        return
    }

    if !output("code_cpp.tpl", "code.cpp") {
        return
    }

    fmt.Println("OK")
}

func parse_token(decoder *xml.Decoder, tt xml.Token, mytoken *Token) {

    token := tt.(xml.StartElement)
    name := token.Name.Local
    mytoken.Name = name

    for _, attr := range token.Attr {
        attrName := attr.Name.Local
        attrValue := attr.Value

        attr := Attribute{Name: attrName, Value: attrValue}

        mytoken.Attributes = append(mytoken.Attributes, attr)
    }

    var t xml.Token
    var err error

    for t, err = decoder.Token(); err == nil; t, err = decoder.Token() {

        switch t.(type) {
            // 处理元素开始(标签)
            case xml.StartElement:

            mytoken.Tokens = append(mytoken.Tokens, Token{})

            parse_token(decoder, t, &mytoken.Tokens[len(mytoken.Tokens)-1])

            // 处理元素结束(标签)
            case xml.EndElement:
            return
            case xml.CharData:
        default:
            return
        }
    }
}

func parse(filename string) bool {
    file, err := os.Open(filename)
    if err != nil {
        fmt.Println(err)
        return false
    }

    var t xml.Token

    decoder := xml.NewDecoder(file)
    t, decerr := decoder.Token()
    if decerr != nil {
        fmt.Println(decerr)
        return false
    }
    parse_token(decoder, t, &result.Root)
    fmt.Println("result", result.Root)
    return true
}

func genlist(n string) []string {
    num, _ := strconv.Atoi(n)
    ret := make([]string, num)
    for i := 0; i < num; i++ {
        ret[i] = strconv.Itoa(i)
    }
    return ret
}

func iconv(str string) string {
    enc := mahonia.NewEncoder("gb2312")
    return enc.ConvertString(str)
}

func output(src string, des string) bool {

    file, err := os.Create(des)
    if err != nil {
        fmt.Println(err)
        return false
    }

    t := template.New("text")
    if err != nil {
        fmt.Println(err)
        return false
    }

    t = t.Funcs(template.FuncMap{"genlist": genlist, "iconv": iconv})

    srcfile, err := os.Open(src)
    if err != nil {
        fmt.Println(err)
        return false
    }

    var buffer [1024 * 1024]byte
    n, rerr := srcfile.Read(buffer[0:])
    if rerr != nil {
        fmt.Println(rerr)
        return false
    }

    t, err = t.Parse(string(buffer[0:n]))
    if err != nil {
        fmt.Println(err)
        return false
    }

    err = t.Execute(file, result.Root)
    if err != nil {
        fmt.Println(err)
        return false
    }

    return true
}