简体   繁体   中英

How to get a value from an XML using XPath in Go

Looking at go xml package I could not find such possibility. Go only allows to define tree of structures, map them to XML tree and deserialize using xml.NewDecoder(myXmlString).Decode(myStruct) .

Even if I define needed tree of Go structures, I still can't query that tree using XPath.

C# has convenient function SelectSingleNode that allows to select value from XML tree by specifying XPath without duplicating whole tree structure in C# classes.

Is there similar possibility in Go ? If not then what is simplest way to implement it (possibly reusing xml package) ?

There is no xpath parsing in the standard packages of Go, so you need to resort to using a 3rd party package.

Then one I know of is Gokogiri
The package is based on libxml2 using cgo

The subpackage you want to import is github.com/moovweb/gokogiri/xpath

There's also the xmlpath package.

Sample usage:

path := xmlpath.MustCompile("/library/book/isbn")
root, err := xmlpath.Parse(file)
if err != nil {
    log.Fatal(err)
}
if value, ok := path.String(root); ok {
    fmt.Println("Found:", value)
}

Even though not xpath, you can read values out of XML with the native go xml encoder package. You would use the xml.Unmarshal() function. Here is a go play example.

package main

import "fmt"
import "encoding/xml"

func main() {
    type People struct {
        Names []string `xml:"Person>FullName"`
    }

    data := `
        <People>
            <Person>
                <FullName>Jerome Anthony</FullName>
            </Person>
            <Person>
                <FullName>Christina</FullName>
            </Person>
        </People>
    `

    v := People{Names: []string{}}
    err := xml.Unmarshal([]byte(data), &v)
    if err != nil {
        fmt.Printf("error: %v", err)
        return
    }
    fmt.Printf("Names of people: %q", v)
}

xmlquery lets you extract data from XML documents using XPath expression.

package main

import (
    "fmt"
    "strings"
    "github.com/antchfx/xmlquery"
)

func main() {
    htmlstr := `<?xml version="1.0" ?>
    <html>
    <head>
     <title>this is a title</title>
    </head>
    <body>Hello,World</body>
    </html>`
    root, err := xmlquery.Parse(strings.NewReader(htmlstr))
    if err != nil {
         panic(err)
     }
    title := xmlquery.FindOne(root, "//title")
    fmt.Println(title.InnerText())
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM