package configUtil import ( "fmt" "goutil/typeUtil" "goutil/xmlUtil" "reflect" "strings" ) type XmlConfig struct { root *xmlUtil.Node } // 从文件加载 // xmlFilePath:xml文件路径 // 返回值: // error:错误信息 func (this *XmlConfig) LoadFromFile(xmlFilePath string) error { if this.root != nil { return fmt.Errorf("There has been an xml file loaded.") } root, err := xmlUtil.LoadFromFile(xmlFilePath) if err != nil { return err } this.root = root return nil } // 从node节点加载(会取其根节点) // xmlRoot:xml节点 // 返回值: // error:错误信息 func (this *XmlConfig) LoadFromXmlNode(xmlRoot *xmlUtil.Node) error { if this.root != nil { return fmt.Errorf("There has been an xml file loaded.") } if xmlRoot == nil { return fmt.Errorf("xmlRoot is nil") } this.root = xmlRoot return nil } // 获取指定xpath路径下的值 // xpath:xpath路径 // attrName:属性名,如果为空,则返回节点的内部文本 //  返回值: // bool:结果 // error:错误信息 func (this *XmlConfig) Bool(xpath string, attrName string) (bool, error) { value, err := this.getVal(xpath, attrName) if err != nil { return false, err } return typeUtil.Bool(value) } // 获取指定xpath路径下的值 // xpath:xpath路径 // attrName:属性名,如果为空,则返回节点的内部文本 // defaultVal:默认值 //  返回值: // bool:结果 func (this *XmlConfig) DefaultBool(xpath string, attrName string, defaultVal bool) bool { value, err := this.Bool(xpath, attrName) if err != nil { return defaultVal } return value } // 获取指定xpath路径下的值 // xpath:xpath路径 // attrName:属性名,如果为空,则返回节点的内部文本 //  返回值: // int:结果 // error:错误信息 func (this *XmlConfig) Int(xpath string, attrName string) (int, error) { value, err := this.getVal(xpath, attrName) if err != nil { return 0, err } return typeUtil.Int(value) } // 获取指定xpath路径下的值 // xpath:xpath路径 // attrName:属性名,如果为空,则返回节点的内部文本 // defaultVal:默认值 //  返回值: // int:结果 func (this *XmlConfig) DefaultInt(xpath string, attrName string, defaultVal int) int { value, err := this.Int(xpath, attrName) if err != nil { return defaultVal } return value } // 获取指定xpath路径下的值 // xpath:xpath路径 // attrName:属性名,如果为空,则返回节点的内部文本 //  返回值: // int64:结果 // error:错误信息 func (this *XmlConfig) Int64(xpath string, attrName string) (int64, error) { value, err := this.getVal(xpath, attrName) if err != nil { return 0, err } return typeUtil.Int64(value) } // 获取指定xpath路径下的值 // xpath:xpath路径 // attrName:属性名,如果为空,则返回节点的内部文本 // defaultVal:默认值 //  返回值: // int64:结果 func (this *XmlConfig) DefaultInt64(xpath string, attrName string, defaultVal int64) int64 { value, err := this.Int64(xpath, attrName) if err != nil { return defaultVal } return value } // 获取指定xpath路径下的值 // xpath:xpath路径 // attrName:属性名,如果为空,则返回节点的内部文本 //  返回值: // float64:结果 // error:错误信息 func (this *XmlConfig) Float(xpath string, attrName string) (float64, error) { value, err := this.getVal(xpath, attrName) if err != nil { return 0, err } return typeUtil.Float64(value) } // 获取指定xpath路径下的值 // xpath:xpath路径 // attrName:属性名,如果为空,则返回节点的内部文本 // defaultVal:默认值 //  返回值: // float64:结果 func (this *XmlConfig) DefaultFloat(xpath string, attrName string, defaultVal float64) float64 { value, err := this.Float(xpath, attrName) if err != nil { return defaultVal } return value } // 获取指定xpath路径下的值 // xpath:xpath路径 // attrName:属性名,如果为空,则返回节点的内部文本 //  返回值: // string:结果 // error:错误信息 func (this *XmlConfig) String(xpath string, attrName string) (string, error) { return this.getVal(xpath, attrName) } // 获取指定xpath路径下的值 // xpath:xpath路径 // attrName:属性名,如果为空,则返回节点的内部文本 // defaultVal:默认值 //  返回值: // string:结果 func (this *XmlConfig) DefaultString(xpath string, attrName string, defaultVal string) string { value, err := this.String(xpath, attrName) if err != nil { return defaultVal } return value } // 获取指定位置的节点 // xpath:xpath路径 // 返回值: // []*xmlUtil.Node:结果 func (this *XmlConfig) Nodes(xpath string) []*xmlUtil.Node { return this.root.SelectElements(xpath) } // 获取指定位置的节点 // xpath:xpath路径 // 返回值: // *xmlUtil.Node:结果 func (this *XmlConfig) Node(xpath string) *xmlUtil.Node { return this.root.SelectElement(xpath) } // 反序列化指定的整个节点 // xpath:xml的path // data:反序列化得到的数据 // 返回值: // error:错误信息 func (this *XmlConfig) Unmarshal(xpath string, data interface{}) error { nodeItem := this.Node(xpath) //不存在节点,这里直接返回空的就行了 if nodeItem == nil { data = nil return nil //return fmt.Errorf("节点不存在,XPATH:%s", xpath) } value := reflect.ValueOf(data) if value.Kind() == reflect.Ptr { value = value.Elem() } dataType := value.Type() // 依次设置字段值 var err error fieldCount := value.NumField() for i := 0; i < fieldCount; i++ { fieldItem := value.Field(i) fieldName := dataType.Field(i).Name // 读取数据 var valueString string tmpXpath := fmt.Sprintf("%s/%s", xpath, fieldName) if valueString, err = this.getVal(tmpXpath, ""); err != nil { valueString, err = this.getVal(xpath, fieldName) if err != nil { // 压根儿无此字段的配置数据,则略过 continue } } // 字符串转换成目标值 fieldValue, err := typeUtil.Convert(valueString, fieldItem.Kind()) if err != nil { return fmt.Errorf("读取字段失败, DataType:%s FieldName:%s Value:%v 错误信息:%v ", dataType.Name(), fieldName, valueString, err) } // 设置到字段上面 valType := reflect.ValueOf(fieldValue) if valType.Type() == fieldItem.Type() { fieldItem.Set(valType) } else { fieldItem.Set(valType.Convert(fieldItem.Type())) } } return nil } // 获取指定路径的之 // xpath:xpath路径 // attrName:要获取的属性值,如果为空,则返回内部文本 func (this *XmlConfig) getVal(xpath string, attrName string) (val string, err error) { targetRoot := this.root.SelectElement(xpath) if targetRoot == nil { err = fmt.Errorf("no find target node:%v", xpath) return } if attrName == "" { val = strings.TrimSpace(targetRoot.InnerText()) return } exist := false val, exist = targetRoot.SelectAttr(attrName) if exist == false { err = fmt.Errorf("no find target attr, node:%v attr:%v", xpath, attrName) return } return } // 创建新的xml配置对象 func NewXmlConfig() *XmlConfig { return &XmlConfig{} }