Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 18 additions & 7 deletions unmarshal.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,7 @@ func unmarshalSelector(s *goquery.Selection, attrV reflect.Value, selector strin
return err
}
case reflect.String:
val := getDOMValue(s.Find(selector), htmlAttr)
attrV.Set(reflect.Indirect(reflect.ValueOf(val)))
unmarshalString(s, selector, htmlAttr, attrV)
case reflect.Struct:
if err := unmarshalStruct(s, selector, attrV); err != nil {
return err
Expand Down Expand Up @@ -126,8 +125,7 @@ func unmarshalAttr(s *goquery.Selection, attrV reflect.Value, attrT reflect.Stru
return err
}
case reflect.String:
val := getDOMValue(s.Find(selector), htmlAttr)
attrV.Set(reflect.Indirect(reflect.ValueOf(val)))
unmarshalString(s, selector, htmlAttr, attrV)
case reflect.Struct:
if err := unmarshalStruct(s, selector, attrV); err != nil {
return err
Expand All @@ -142,6 +140,15 @@ func unmarshalAttr(s *goquery.Selection, attrV reflect.Value, attrT reflect.Stru
return nil
}

func unmarshalString(s *goquery.Selection, selector string, htmlAttr string, attrV reflect.Value) {
newS := s
if selector != "" {
newS = newS.Find(selector)
}
val := getDOMValue(newS, htmlAttr)
attrV.Set(reflect.Indirect(reflect.ValueOf(val)))
}

func unmarshalStruct(s *goquery.Selection, selector string, attrV reflect.Value) error {
newS := s
if selector != "" {
Expand Down Expand Up @@ -185,20 +192,24 @@ func unmarshalSlice(s *goquery.Selection, selector, htmlAttr string, attrV refle
v := reflect.MakeSlice(attrV.Type(), 0, 0)
attrV.Set(v)
}
newS := s
if selector != "" {
newS = newS.Find(selector)
}
switch attrV.Type().Elem().Kind() {
case reflect.String:
s.Find(selector).Each(func(_ int, s *goquery.Selection) {
newS.Each(func(_ int, s *goquery.Selection) {
val := getDOMValue(s, htmlAttr)
attrV.Set(reflect.Append(attrV, reflect.Indirect(reflect.ValueOf(val))))
})
case reflect.Ptr:
s.Find(selector).Each(func(_ int, innerSel *goquery.Selection) {
newS.Each(func(_ int, innerSel *goquery.Selection) {
someVal := reflect.New(attrV.Type().Elem().Elem())
UnmarshalHTML(someVal.Interface(), innerSel, nil)
attrV.Set(reflect.Append(attrV, someVal))
})
case reflect.Struct:
s.Find(selector).Each(func(_ int, innerSel *goquery.Selection) {
newS.Each(func(_ int, innerSel *goquery.Selection) {
someVal := reflect.New(attrV.Type().Elem())
UnmarshalHTML(someVal.Interface(), innerSel, nil)
attrV.Set(reflect.Append(attrV, reflect.Indirect(someVal)))
Expand Down
19 changes: 17 additions & 2 deletions unmarshal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import (

var basicTestData = []byte(`<ul><li class="x">list <span>item</span> 1</li><li>list item 2</li><li>3</li></ul>`)
var nestedTestData = []byte(`<div><p>a</p><div><p>b</p><div><p>c</p></div></div></div>`)
var pointerSliceTestData = []byte(`<ul class="object"><li class="info">Information: <span>Info 1</span></li><li class="info">Information: <span>Info 2</span></li></ul>`)
var pointerSliceTestData = []byte(`<ul class="object"><li class="info">Information: <span>Info 1</span></li><li class="info">Information: <span>Info 2</span></li> <a href="url1">Name 1</a><a href="url2">Name 2</a></ul>`)

func TestBasicUnmarshal(t *testing.T) {
doc, _ := goquery.NewDocumentFromReader(bytes.NewBuffer(basicTestData))
Expand Down Expand Up @@ -138,8 +138,14 @@ func TestStructSliceUnmarshall(t *testing.T) {
type info struct {
Text string `selector:"span"`
}
type urlWithName struct {
Name string `selector:""`
URL string `selector:"" attr:"href"`
}

type object struct {
Info []info `selector:"li.info"`
Info []info `selector:"li.info"`
Urls []*urlWithName `selector:"a"`
}

doc, _ := goquery.NewDocumentFromReader(bytes.NewBuffer(pointerSliceTestData))
Expand All @@ -160,4 +166,13 @@ func TestStructSliceUnmarshall(t *testing.T) {
t.Errorf("Invalid data for Info.[1].Text: %s, expected Info 2", o.Info[1].Text)
}

if len(o.Urls) != 2 {
t.Errorf("Invalid length for Urls: %d, expected 2", len(o.Info))
}
if o.Urls[0].Name != "Name 1" || o.Urls[0].URL != "url1" {
t.Errorf("Invalid data for Urls.[0].Name: %s or Urls.[0].URL: %s, expected Name 1 and url1", o.Urls[0].Name, o.Urls[0].URL)
}
if o.Urls[1].Name != "Name 2" || o.Urls[1].URL != "url2" {
t.Errorf("Invalid data for Urls.[1].Name: %s or Urls.[1].URL: %s, expected Name 2 and url2", o.Urls[1].Name, o.Urls[1].URL)
}
}