github.com/go-spring/spring-base@v1.1.3/log/log_reader.go (about) 1 /* 2 * Copyright 2012-2019 the original author or authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * https://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package log 18 19 import ( 20 "bytes" 21 "encoding/xml" 22 "errors" 23 "io" 24 ) 25 26 var ( 27 readers = map[string]Reader{} 28 ) 29 30 func init() { 31 RegisterReader(new(XMLReader), ".xml") 32 } 33 34 type Node struct { 35 Label string 36 Children []*Node 37 Attributes map[string]string 38 } 39 40 func (node *Node) child(label string) *Node { 41 for _, c := range node.Children { 42 if c.Label == label { 43 return c 44 } 45 } 46 return nil 47 } 48 49 // Reader 配置项解析器。 50 type Reader interface { 51 Read(b []byte) (*Node, error) 52 } 53 54 // RegisterReader 注册配置项解析器。 55 func RegisterReader(r Reader, ext ...string) { 56 for _, s := range ext { 57 readers[s] = r 58 } 59 } 60 61 type XMLReader struct{} 62 63 func (r *XMLReader) Read(b []byte) (*Node, error) { 64 stack := []*Node{{Label: "<<STACK>>"}} 65 d := xml.NewDecoder(bytes.NewReader(b)) 66 for { 67 token, err := d.Token() 68 if err == io.EOF { 69 break 70 } 71 if err != nil { 72 return nil, err 73 } 74 switch t := token.(type) { 75 case xml.StartElement: 76 curr := &Node{ 77 Label: t.Name.Local, 78 Attributes: make(map[string]string), 79 } 80 for _, attr := range t.Attr { 81 curr.Attributes[attr.Name.Local] = attr.Value 82 } 83 stack = append(stack, curr) 84 case xml.EndElement: 85 curr := stack[len(stack)-1] 86 parent := stack[len(stack)-2] 87 parent.Children = append(parent.Children, curr) 88 stack = stack[:len(stack)-1] 89 } 90 } 91 if len(stack[0].Children) == 0 { 92 return nil, errors.New("error xml config file") 93 } 94 return stack[0].Children[0], nil 95 }