Golang:结构错误中的未定义字段

I am trying to parse an xml file using golang. I have created my structs needed but when I try to compile the go file, I get an error saying the following:

./main_v4.go:146: aggInfoXml.IpAddr.Hports undefined (type []Addr has no field or method Hports)

I am stumped on this problem. Here is my code:

package main

import(
    "net/http"
    "html/template"
    "os/exec"
    "io/ioutil"
    "os"
    "encoding/xml"
    "encoding/json"
    "fmt"
    "bufio"
    "github.com/gorilla/websocket"
    "time"
    "log"

)

type PercentInfo struct {
    Percent IntPercent `xml:"taskprogress,omitempty"`
} 

type AggInfoXml struct {
    Percent     IntPercent  `xml:"taskprogress,omitempty"`
    IpAddr      []Addr      `xml:"host>address,omitempty"`
}

type IntPercent struct {
    Value float64 `xml:"percent,attr,omitempty"` // works
}


type Addr struct {
    Ip      string   `xml:"addr,attr"`
    Hports  []Ports  `xml:"host>ports>port,omitempty"` //failing to be recognized
}

type Ports struct {
    Port string `xml:"portid,attr"`
}

func (p *Addr) ipaddr() string {
     return p.Ip
}

func (p *Ports) ports() string {
     return p.Port
}

func (p *IntPercent) percent() float64 {
    return p.Value
}

func (f *Test) Name() string {
    return f.Value

}

var upgrader = websocket.Upgrader{
    ReadBufferSize: 1024,
    WriteBufferSize: 1024,
}

type Test struct {
    Value string    
}


func wsHandler(w http.ResponseWriter, r *http.Request) {

    conn, err := upgrader.Upgrade(w, r, nil)
    if err != nil {
        fmt.Println(err)
    }

    cmd := exec.Command("nmap", "-F", "-sS", "172.16.2.0/24", "-oX", "output.xml", "--stats-every", "1s")

    if err := cmd.Start(); err != nil {
        log.Fatal(err)
    }

    time.Sleep( 1000 * time.Millisecond) 

    fp, err := os.Open("output.xml")
    if err != nil {
        log.Fatal(err)
    }


    // create scanner on the output.xml file
    in := bufio.NewScanner(fp)

    // change this loop to buffer read the xml file...
    aggInfoXml  := AggInfoXml{}

    fmt.Printf("hello")

    for in.Scan() {

        err = xml.Unmarshal([]byte(in.Text()), &aggInfoXml.Percent) 
        if err != nil {
            fmt.Printf("Could not unmarshal the line <%v>", in.Text())
        } else {
            fmt.Printf("%+v
", aggInfoXml.Percent.Value)
        }

        // bail out of slow loop if 100% reached
        if aggInfoXml.Percent.Value == 100 {
            break
        }

        time.Sleep(1000*time.Millisecond)

        bytesArray, err := json.Marshal(aggInfoXml.Percent)

        err = conn.WriteMessage(websocket.TextMessage, bytesArray)  // send JSON over
        if err != nil {
            panic(err)
        }

    }//this is the end of the in.Scan loop now

    fmt.Println("After loop")

    if err := cmd.Wait(); err != nil {  
        log.Fatal(err)
    }

    data, err := ioutil.ReadFile("output.xml")

    if err != nil {
        panic(err)
    }

    err = xml.Unmarshal(data, &aggInfoXml.IpAddr)
    if err != nil {
        log.Fatal("Could not unmarshal host")
    }

    for _, port := range aggInfoXml.IpAddr.Hports {
        fmt.Printf("Port: %s
", port.ports())
    }

    for _, ip := range aggInfoXml.IpAddr {
        fmt.Printf("IpAdd: %s
", ip.ipaddr())
    }

    conn.Close()
    fp.Close()
}

func handler(w http.ResponseWriter, r *http.Request) {

    t, _ := template.ParseFiles("index.html")
    t.Execute(w,nil)
}

func main() {

    http.HandleFunc("/", handler)
    http.Handle("/layout/", http.StripPrefix("/layout/", http.FileServer(http.Dir("layout"))))
    http.HandleFunc("/websocket", wsHandler)
    http.ListenAndServe(":8080", nil) 
}

Any suggestions would be helpful.

type AggInfoXml struct {
    Percent     IntPercent  `xml:"taskprogress,omitempty"`
    IpAddr      []Addr      `xml:"host>address,omitempty"`
}




type Addr struct {
    Ip      string   `xml:"addr,attr"`
    Hports  []Ports  `xml:"host>ports>port,omitempty"` //failing to be recognized
}

IpAddr is an Array. It has no attribute called Hports. You will have to refer one of the elements of that array like this.

aggInfoXml.IpAddr[0].Hports 

but if you want to access port of Hports, then you will have to do this.

aggInfoXml.IpAddr[0].Hports[0] 

I have upvoted the answer from Prajwal as it points to the problem, but actually, in your code it seems you should be replacing your for loops with something like this:

for _, ip := range aggInfoXml.IpAddr {
    fmt.Printf("IpAdd: %s
", ip.ipaddr())

    for _, port := range ip.Hports {
        fmt.Printf("Port: %s
", port.ports())
    }
}