84 lines
2.1 KiB
Go
84 lines
2.1 KiB
Go
package main
|
||
|
||
import (
|
||
"Study/src/study/day7Function/HtmlTools"
|
||
"fmt"
|
||
"golang.org/x/net/html"
|
||
"reflect"
|
||
)
|
||
|
||
func main() {
|
||
// 同样的,函数可以作为参数传入另一个函数
|
||
// forEachNode针对每个结点x,都会调用pre(x)和post(x)。
|
||
// pre和post都是可选的。
|
||
// 遍历孩子结点之前,pre被调用
|
||
// 遍历孩子结点之后,post被调用
|
||
var forEachNode func(n *html.Node, pre, post func(n *html.Node))
|
||
forEachNode = func(n *html.Node, pre, post func(n *html.Node)) {
|
||
if pre != nil {
|
||
pre(n)
|
||
}
|
||
for c := n.FirstChild; c != nil; c = c.NextSibling {
|
||
forEachNode(c, pre, post)
|
||
}
|
||
if post != nil {
|
||
post(n)
|
||
}
|
||
}
|
||
var depth int
|
||
var ExcludeNodes []string = []string{
|
||
"link",
|
||
"img",
|
||
"meta",
|
||
}
|
||
// 断言
|
||
m, _ := ToMapSetStrictE(ExcludeNodes)
|
||
ExcludeNodesMap := m.(map[string]struct{})
|
||
startElemen := func(n *html.Node) {
|
||
if n.Type == html.ElementNode {
|
||
fmt.Printf("%*s<%s", depth*2, "", n.Data)
|
||
for _, attr := range n.Attr {
|
||
fmt.Printf(" %s=\"%s\"", attr.Key, attr.Val)
|
||
}
|
||
// 检测单节点
|
||
if _, ok := ExcludeNodesMap[n.Data]; ok {
|
||
fmt.Println(" />")
|
||
} else {
|
||
fmt.Println(">")
|
||
}
|
||
depth++
|
||
}
|
||
}
|
||
endElement := func(n *html.Node) {
|
||
if n.Type == html.ElementNode {
|
||
depth--
|
||
// 检测单节点
|
||
if _, ok := ExcludeNodesMap[n.Data]; !ok {
|
||
fmt.Printf("%*s</%s>\n", depth*2, "", n.Data)
|
||
}
|
||
}
|
||
}
|
||
forEachNode(HtmlTools.GetHtml(), startElemen, endElement)
|
||
}
|
||
|
||
// 借助一个空接口,使切片转为map
|
||
func ToMapSetStrictE(i interface{}) (interface{}, error) {
|
||
// check param
|
||
if i == nil {
|
||
return nil, fmt.Errorf("unable to converts %#v of type %T to map[interface{}]struct{}", i, i)
|
||
}
|
||
t := reflect.TypeOf(i)
|
||
kind := t.Kind()
|
||
if kind != reflect.Slice && kind != reflect.Array {
|
||
return nil, fmt.Errorf("the input %#v of type %T isn't a slice or array", i, i)
|
||
}
|
||
// execute the convert
|
||
v := reflect.ValueOf(i)
|
||
mT := reflect.MapOf(t.Elem(), reflect.TypeOf(struct{}{}))
|
||
mV := reflect.MakeMapWithSize(mT, v.Len())
|
||
for j := 0; j < v.Len(); j++ {
|
||
mV.SetMapIndex(v.Index(j), reflect.ValueOf(struct{}{}))
|
||
}
|
||
return mV.Interface(), nil
|
||
}
|