You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

84 lines
2.0 KiB

package axml
import (
"regexp"
"strings"
)
func newSys(options Options) (sys ISys, err error) {
sys = &AXml{}
return
}
// XMLItem 表示一个通用的 XML 数据项
type XMLItem struct {
TagName string // 标签名
Attributes map[string]string // 属性键值对
Content string // 标签内容
}
type AXml struct {
source string
buffer string
items []*XMLItem
}
func (this *AXml) Add(data string) (err error) {
this.source += data
this.buffer += data
this.processData()
return
}
func (this *AXml) Get(name string) (items []*XMLItem) {
items = make([]*XMLItem, 0)
for _, v := range this.items {
if v.TagName == name {
items = append(items, v)
}
}
return
}
// 解析数据
func (this *AXml) processData() {
// 匹配完整的 <tag attr="value">content</tag> 模式
// 捕获标签名、属性和内容
re := regexp.MustCompile(`<([a-zA-Z][^>]*)>((?:[^<]|<[^/])*?)</([a-zA-Z][^>]*)>`)
matches := re.FindAllStringSubmatch(this.buffer, -1)
// var items []XMLItem
for _, match := range matches {
if len(match) != 4 {
continue
}
// match[0] 是完整匹配,match[1] 是标签和属性部分,match[2] 是内容
tagAndAttrs := match[1]
content := match[2]
// 解析标签名和属性
attrRe := regexp.MustCompile(`([a-zA-Z]+)(?: *= *"([^"]*)")?`)
attrMatches := attrRe.FindAllStringSubmatch(tagAndAttrs, -1)
item := &XMLItem{
Attributes: make(map[string]string),
}
for _, attrMatch := range attrMatches {
if len(attrMatch) >= 2 {
if item.TagName == "" {
item.TagName = attrMatch[1] // 第一个捕获组是标签名
}
if len(attrMatch) == 3 && attrMatch[2] != "" {
item.Attributes[attrMatch[1]] = attrMatch[2] // 属性名和值
}
}
}
item.Content = strings.TrimSpace(content)
if item.TagName != "" {
this.items = append(this.items, item)
// 从缓冲区移除已解析的部分
this.buffer = this.buffer[strings.Index(this.buffer, match[0])+len(match[0]):]
}
}
}