Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
包含*html.Node的递归函数,用于打印html文档中的所有链接_Html_Go_Recursion_Tree_Nodes - Fatal编程技术网

包含*html.Node的递归函数,用于打印html文档中的所有链接

包含*html.Node的递归函数,用于打印html文档中的所有链接,html,go,recursion,tree,nodes,Html,Go,Recursion,Tree,Nodes,我试图使用一个接受*HTML.Node作为参数的函数来打印HTML文档中的所有链接。我对Golang和*html.Node数据类型都是新手,以前从未使用过它们 func visit(links []string, n *html.Node) []string { if n == nil { return links } if n.Type == html.ElementNode && n.Data == "a" {

我试图使用一个接受*HTML.Node作为参数的函数来打印HTML文档中的所有链接。我对Golang和*html.Node数据类型都是新手,以前从未使用过它们

func visit(links []string, n *html.Node) []string {
    if n == nil {
        return links
    }
    if n.Type == html.ElementNode && n.Data == "a" {
        for _, a := range n.Attr {
            if a.Key == "href" {
                links = append(links, a.Val)
            }
        }
    }
    if i == 0 {
        i++
        return visit(links, n.FirstChild)
    }
    return visit(links, n.NextSibling)
}
检查
i==0
的if块的目的是确保
回访(links,n.FirstChild)
只运行一次(第一次)和
回访(links,n.NextSibling)
在以下迭代中运行。但是,
链接
永远不会追加,并且总是返回一个空片段。我不理解代码中的错误

当使用for循环时,代码工作得非常好,但当我尝试使用递归时,代码会中断

for c := n.FirstChild; c != nil; c = c.NextSibling {
        links = visit(links, c)
    }

您的代码不起作用,因为它取文档的第一个子元素,即
html
元素,然后取其同级元素,即
nil
,从而导致函数以空链接片段结束

详细说明: 下面是一个示例代码

package main

import (
    "fmt"
    "log"
    "strings"

    "golang.org/x/net/html"
)

var i int = 0

func visit(links []string, n *html.Node) []string {

    if n == nil {
        return links
    }

    if n.Type == html.ElementNode && n.Data == "a" {
        for _, a := range n.Attr {
            if a.Key == "href" {
                links = append(links, a.Val)
            }
        }
    }

    if i == 0 {
        i++
        return visit(links, n.FirstChild)
    }

    return visit(links, n.NextSibling)
}

func main() {
    s := `<p>Links:</p><ul><li><a href="foo">Foo</a><li><a href="/bar/baz">BarBaz</a></ul>`

    doc, err := html.Parse(strings.NewReader(s))
    if err != nil {
        log.Fatal(err)
    }

    links := visit([]string{}, doc)

    fmt.Println(links)
}

在这里,循环通过检查每个HTML元素的子元素来帮助递归地查找链接。如果其中一个HTML元素没有同级元素,那么它只需移动到其父元素的下一个同级元素并检查

您问题中的变量
i
是否未定义?我已将main/func块外的变量i声明为全局变量
package main

import (
    "fmt"
    "log"
    "strings"

    "golang.org/x/net/html"
)

func visit(links []string, n *html.Node) []string {

    if n.Type == html.ElementNode && n.Data == "a" {
        for _, a := range n.Attr {
            if a.Key == "href" {
                links = append(links, a.Val)
            }
        }
    }

    for c := n.FirstChild; c != nil; c = c.NextSibling {
        links = visit(links, c)
    }

    return links
}

func main() {
    s := `<p>Links:</p><ul><li><a href="foo">Foo</a><li><a href="/bar/baz">BarBaz</a></ul>`

    doc, err := html.Parse(strings.NewReader(s))
    if err != nil {
        log.Fatal(err)
    }

    links := visit([]string{}, doc)

    fmt.Println(links)
}