diff --git a/function.go b/function.go index 1776f8d..006e337 100644 --- a/function.go +++ b/function.go @@ -263,6 +263,6 @@ func (builtin BuiltinFunctions) EqAndOutHtml(node *goquery.Selection, args ...st // RegisterFunc register function for parse func (p *Pagser) RegisterFunc(name string, fn CallFunc) error { - p.funcs[name] = fn + p.ctxFuncs[name] = fn return nil } diff --git a/pagser.go b/pagser.go index 109cf3d..4c3de4d 100644 --- a/pagser.go +++ b/pagser.go @@ -12,9 +12,9 @@ import "errors" // Pagser the page parser type Pagser struct { - config Config - tagers map[string]*Tager // tager value => Tager - funcs map[string]CallFunc // name => func + config Config + ctxTags map[string]*parseTag // tag value => parseTag + ctxFuncs map[string]CallFunc // name => func } // New create client @@ -35,9 +35,9 @@ func NewWithConfig(cfg Config) (*Pagser, error) { return nil, errors.New("IgnoreSymbol must not empty") } return &Pagser{ - config: cfg, - tagers: make(map[string]*Tager, 0), - funcs: builtinFuncMap, + config: cfg, + ctxTags: make(map[string]*parseTag, 0), + ctxFuncs: builtinFuncMap, }, nil } diff --git a/parse.go b/parse.go index b64587f..61ca077 100644 --- a/parse.go +++ b/parse.go @@ -60,7 +60,7 @@ func (p *Pagser) doParse(v interface{}, stackRefValues []reflect.Value, selectio tagValue, tagOk := fieldType.Tag.Lookup(p.config.TagerName) if !tagOk { if p.config.Debug { - fmt.Printf("[WARN] not found tager name=[%v] in field: %v, eg: `%v:\".navlink a->attr(href)\"`\n", + fmt.Printf("[WARN] not found tag name=[%v] in field: %v, eg: `%v:\".navlink a->attr(href)\"`\n", p.config.TagerName, fieldType.Name, p.config.TagerName) } continue @@ -69,21 +69,21 @@ func (p *Pagser) doParse(v interface{}, stackRefValues []reflect.Value, selectio continue } - tager, ok := p.tagers[tagValue] - if !ok || tager == nil { - tager = p.newTager(tagValue) - p.tagers[tagValue] = tager + tag, ok := p.ctxTags[tagValue] + if !ok || tag == nil { + tag = p.newTag(tagValue) + p.ctxTags[tagValue] = tag } node := selection - if tager.Selector != "" { - node = selection.Find(tager.Selector) + if tag.Selector != "" { + node = selection.Find(tag.Selector) } var callOutValue interface{} var callErr error - if tager.FuncName != "" { - callOutValue, callErr = p.findAndExecFunc(objRefValue, stackRefValues, tager, node) + if tag.FuncName != "" { + callOutValue, callErr = p.findAndExecFunc(objRefValue, stackRefValues, tag, node) if callErr != nil { return fmt.Errorf("tag=`%v` parse func error: %v", tagValue, callErr) } @@ -137,9 +137,9 @@ func (p *Pagser) doParse(v interface{}, stackRefValues []reflect.Value, selectio } default: //slice.Index(i).Set(itemValue) - if tager.FuncName != "" { - itemOutValue, itemErr := p.findAndExecFunc(objRefValue, stackRefValues, tager, subNode) - //fmt.Printf("call slice func %v value: %v\n", tager.FuncName, itemOutValue) + if tag.FuncName != "" { + itemOutValue, itemErr := p.findAndExecFunc(objRefValue, stackRefValues, tag, subNode) + //fmt.Printf("call slice func %v value: %v\n", tag.FuncName, itemOutValue) if itemErr != nil { err = fmt.Errorf("tag=`%v` parse slice item error: %v", tagValue, itemErr) return false @@ -184,7 +184,7 @@ func (p *Pagser) doParse(v interface{}, stackRefValues []reflect.Value, selectio fieldType := refTypeElem.Field(i) fieldValue := refValueElem.Field(i) */ -func (p *Pagser) findAndExecFunc(objRefValue reflect.Value, stackRefValues []reflect.Value, selTag *Tager, node *goquery.Selection) (interface{}, error) { +func (p *Pagser) findAndExecFunc(objRefValue reflect.Value, stackRefValues []reflect.Value, selTag *parseTag, node *goquery.Selection) (interface{}, error) { if selTag.FuncName != "" { //call object method @@ -207,7 +207,7 @@ func (p *Pagser) findAndExecFunc(objRefValue reflect.Value, stackRefValues []ref } //global function - if fn, ok := p.funcs[selTag.FuncName]; ok { + if fn, ok := p.ctxFuncs[selTag.FuncName]; ok { outValue, err := fn(node, selTag.FuncParams...) if err != nil { return nil, fmt.Errorf("call registered func %v error: %v", selTag.FuncName, err) @@ -230,7 +230,7 @@ func findMethod(objRefValue reflect.Value, funcName string) reflect.Value { return objRefValue.Elem().MethodByName(funcName) } -func execMethod(callMethod reflect.Value, selTag *Tager, node *goquery.Selection) (interface{}, error) { +func execMethod(callMethod reflect.Value, selTag *parseTag, node *goquery.Selection) (interface{}, error) { callParams := make([]reflect.Value, 0) callParams = append(callParams, reflect.ValueOf(node)) diff --git a/pagser_test.go b/parse_test.go similarity index 84% rename from pagser_test.go rename to parse_test.go index d266d34..926082e 100644 --- a/pagser_test.go +++ b/parse_test.go @@ -10,7 +10,8 @@ import ( type PageData struct { Title string `pagser:"title"` Keywords []string `pagser:"meta[name='keywords']->attrSplit(content)"` - H1 string `pagser:"h1->text()"` + H1 string `pagser:"h1"` + H1Text string `pagser:"h1->text()"` H1Html string `pagser:"h1->html()"` H1OutHtml string `pagser:"h1->outerHtml()"` MyGlobalFuncValue string `pagser:"h1->MyGlobFunc()"` @@ -19,7 +20,7 @@ type PageData struct { FillFieldOtherValue string //Set value by FillFieldFunc() NavList []struct { ID int `pagser:"a->attrInt(id, -1)"` - Name string `pagser:"a"` + Name string `pagser:"a->text()"` Url string `pagser:"a->attr(href)"` ParentFuncName string `pagser:"a->ParentFunc()"` } `pagser:".navlink li"` @@ -35,6 +36,7 @@ type PageData struct { NavEqOutHtml string `pagser:".navlink li->eqAndOutHtml(1)"` WordsSplitArray []string `pagser:".words->split(|)"` Value string `pagser:"input[name='feedback']->value()"` + SameFuncValue string `pagser:"h1->SameFunc()"` SubPageData *SubPageData `pagser:".navlink li:last-child"` } @@ -43,6 +45,11 @@ func MyGlobalFunc(selection *goquery.Selection, args ...string) (out interface{} return "Global-" + selection.Text(), nil } +// this method will auto call, not need register. +func SameFunc(selection *goquery.Selection, args ...string) (out interface{}, err error) { + return "Global-Same-Func-" + selection.Text(), nil +} + // this method will auto call, not need register. func (pd PageData) MyStructFunc(selection *goquery.Selection, args ...string) (out interface{}, err error) { return "Struct-" + selection.Text(), nil @@ -59,16 +66,25 @@ func (pd *PageData) FillFieldFunc(selection *goquery.Selection, args ...string) return "FillFieldFunc-" + text, nil } +func (pd *PageData) SameFunc(selection *goquery.Selection, args ...string) (out interface{}, err error) { + return "Struct-Same-Func-" + selection.Text(), nil +} + type SubPageData struct { Text string `pagser:"->text()"` SubFuncValue string `pagser:"->SubFunc()"` ParentFuncValue string `pagser:"->ParentFunc()"` + SameFuncValue string `pagser:"->SameFunc()"` } func (spd SubPageData) SubFunc(selection *goquery.Selection, args ...string) (out interface{}, err error) { return "SubFunc-" + selection.Text(), nil } +func (spd SubPageData) SameFunc(selection *goquery.Selection, args ...string) (out interface{}, err error) { + return "Sub-Struct-Same-Func-" + selection.Text(), nil +} + const rawPpageHtml = ` @@ -106,6 +122,7 @@ func TestParse(t *testing.T) { //register global function p.RegisterFunc("MyGlobFunc", MyGlobalFunc) + p.RegisterFunc("SameFunc", SameFunc) var data PageData err = p.Parse(&data, rawPpageHtml) diff --git a/tager.go b/tag.go similarity index 83% rename from tager.go rename to tag.go index e30b9a5..3d675b0 100644 --- a/tager.go +++ b/tag.go @@ -20,16 +20,16 @@ var rxFunc = regexp.MustCompile("^\\s*([a-zA-Z]+)\\s*(\\(([^\\)]*)\\))?\\s*$") // ignoreTagSymbol = "-" //) -// Tager struct tag info -type Tager struct { +// parseTag struct tag info +type parseTag struct { Selector string FuncName string FuncParams []string } -func (p *Pagser) newTager(tagValue string) *Tager { +func (p *Pagser) newTag(tagValue string) *parseTag { //fmt.Println("tag value: ", tagValue) - cssParser := &Tager{} + cssParser := &parseTag{} if tagValue == "" { return cssParser } @@ -43,13 +43,13 @@ func (p *Pagser) newTager(tagValue string) *Tager { funcValue = selectors[i] } } - matchs := rxFunc.FindStringSubmatch(funcValue) - if len(matchs) < 3 { + matches := rxFunc.FindStringSubmatch(funcValue) + if len(matches) < 3 { return cssParser } - cssParser.FuncName = strings.TrimSpace(matchs[1]) - //cssParser.FuncParams = strings.Split(matchs[2], ",") - cssParser.FuncParams = parseFuncParams(matchs[3]) + cssParser.FuncName = strings.TrimSpace(matches[1]) + //cssParser.FuncParams = strings.Split(matches[2], ",") + cssParser.FuncParams = parseFuncParams(matches[3]) if p.config.Debug { fmt.Printf("----- debug -----\n`%v`\n%v\n", tagValue, prettyJson(cssParser)) } diff --git a/tager_test.go b/tag_test.go similarity index 100% rename from tager_test.go rename to tag_test.go