package graph import ( "errors" "log" ) var attributeNameLaw map[rune]bool = make(map[rune]bool) func init() { for _, c := range "abcdefghijklmnopqrstuvwsyzABCDEFGHIJKLMNOPQRSTUVWSYZ-_" { attributeNameLaw[c] = true } } type Range struct { Start int End int } type ElementTag struct { Range } type Element struct { Range Tag *ElementTag Attributes []*Attribute Source []rune Children []*Element Text []string } type Attribute struct { Range Key Range Value Range } func (e *Element) GetTagName() string { return string(e.Source[e.Tag.Start:e.Tag.End]) } func GetTag(source []rune, cur int) (*ElementTag, int) { for i := cur; i < len(source); i++ { c := source[i] if c == ' ' { return &ElementTag{Range{cur, i - 1}}, i } } return nil, -1 } func SkipAttribute(source []rune, cur int) int { for i := cur; i < len(source); i++ { c := source[i] if c == ' ' || c == '>' { return i - 1 } } panic(errors.New("over the range of the next attribute")) } func GetAttribute(source []rune, cur int) *Range { return nil } func GetAttributes(source []rune, cur int) []*Attribute { var attrs []*Attribute LOOP_TOP: for i := cur; i < len(source); i++ { c := source[i] switch c { case '>': break LOOP_TOP case '/': if source[i+1] == '>' { break LOOP_TOP } case ' ': continue default: attr := &Attribute{} attr.Range.Start = i for ; i < len(source); i++ { c = source[i] if _, ok := attributeNameLaw[c]; ok { if c == ' ' || c == '>' { attr.Range.End = i break } } else { i = SkipAttribute(source, i) break } } if attr.Range.End != 0 { attrs = append(attrs, attr) } } } return attrs } func ParseChild(parent *Element, cur int) (*Element, int) { start := cur end := start child := &Element{} child.Tag, cur = GetTag(parent.Source, start) child.Attributes = GetAttributes(parent.Source, cur) open := 1 for i := cur; i < len(parent.Source); i++ { c := parent.Source[i] if c == '>' { if parent.Source[i-1] == '\\' { end = i - 1 return child, i } else { for { } } } } return nil, cur } func GetChildren(parent *Element) (result []*Element) { // GetChild for i := parent.Range.Start; i < parent.Range.End; i++ { c := parent.Source[i] var child *Element if c == '<' { child, i = ParseChild(parent, i) log.Println(child) result = append(result, child) } } return } func ParseXML(data []byte) *Element { source := []rune(string(data)) root := &Element{Tag: nil, Source: source, Range: Range{0, len(source)}} return root }