xmltree/graph.go

167 lines
2.6 KiB
Go
Raw Permalink Normal View History

2019-11-29 10:30:20 +00:00
package graph
import (
"errors"
"log"
)
2019-12-02 11:38:30 +00:00
var attributeNameLaw map[rune]bool = make(map[rune]bool)
2019-11-29 10:30:20 +00:00
func init() {
for _, c := range "abcdefghijklmnopqrstuvwsyzABCDEFGHIJKLMNOPQRSTUVWSYZ-_" {
2019-12-02 11:38:30 +00:00
attributeNameLaw[c] = true
2019-11-29 10:30:20 +00:00
}
}
type Range struct {
Start int
End int
}
type ElementTag struct {
Range
}
type Element struct {
Range
Tag *ElementTag
Attributes []*Attribute
Source []rune
Children []*Element
2019-12-02 11:38:30 +00:00
Text []string
2019-11-29 10:30:20 +00:00
}
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 {
2019-12-02 11:38:30 +00:00
return nil
2019-11-29 10:30:20 +00:00
}
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]
2019-12-02 11:38:30 +00:00
if _, ok := attributeNameLaw[c]; ok {
2019-11-29 10:30:20 +00:00
if c == ' ' || c == '>' {
attr.Range.End = i
break
}
2019-12-02 11:38:30 +00:00
} else {
i = SkipAttribute(source, i)
break
2019-11-29 10:30:20 +00:00
}
}
2019-12-02 11:38:30 +00:00
if attr.Range.End != 0 {
attrs = append(attrs, attr)
}
2019-11-29 10:30:20 +00:00
}
}
return attrs
}
2019-12-02 11:38:30 +00:00
func ParseChild(parent *Element, cur int) (*Element, int) {
2019-11-29 10:30:20 +00:00
start := cur
end := start
child := &Element{}
child.Tag, cur = GetTag(parent.Source, start)
2019-12-02 11:38:30 +00:00
child.Attributes = GetAttributes(parent.Source, cur)
2019-11-29 10:30:20 +00:00
2019-12-02 11:38:30 +00:00
open := 1
2019-11-29 10:30:20 +00:00
for i := cur; i < len(parent.Source); i++ {
c := parent.Source[i]
if c == '>' {
2019-12-02 11:38:30 +00:00
if parent.Source[i-1] == '\\' {
end = i - 1
return child, i
} else {
for {
2019-11-29 10:30:20 +00:00
2019-12-02 11:38:30 +00:00
}
}
}
2019-11-29 10:30:20 +00:00
}
2019-12-02 11:38:30 +00:00
return nil, cur
2019-11-29 10:30:20 +00:00
}
2019-12-02 11:38:30 +00:00
func GetChildren(parent *Element) (result []*Element) {
2019-11-29 10:30:20 +00:00
// GetChild
for i := parent.Range.Start; i < parent.Range.End; i++ {
c := parent.Source[i]
2019-12-02 11:38:30 +00:00
var child *Element
2019-11-29 10:30:20 +00:00
if c == '<' {
2019-12-02 11:38:30 +00:00
child, i = ParseChild(parent, i)
log.Println(child)
result = append(result, child)
2019-11-29 10:30:20 +00:00
}
}
2019-12-02 11:38:30 +00:00
return
2019-11-29 10:30:20 +00:00
}
func ParseXML(data []byte) *Element {
source := []rune(string(data))
2019-12-02 11:38:30 +00:00
root := &Element{Tag: nil, Source: source, Range: Range{0, len(source)}}
2019-11-29 10:30:20 +00:00
return root
}