如何在Go中使用XPath从XML中获取值

huangapple go评论90阅读模式
英文:

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

问题

在查看go xml package时,我没有找到这样的可能性。
Go只允许定义结构树,将其映射到XML树并使用<code>xml.NewDecoder(myXmlString).Decode(myStruct)</code>进行反序列化。

即使我定义了所需的Go结构树,我仍然无法使用XPath查询该树。

C#有一个方便的函数SelectSingleNode,可以通过指定XPath从XML树中选择值,而无需在C#类中复制整个树结构。

Go中是否有类似的可能性?
如果没有,那么实现它的最简单方法是什么(可能可以重用xml包)?

英文:

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 <code>xml.NewDecoder(myXmlString).Decode(myStruct)</code>.

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) ?

答案1

得分: 15

还有一个xmlpath包。

示例用法:

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("找到:", value)
}
英文:

There's also the xmlpath package.

Sample usage:

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

答案2

得分: 14

在Go的标准包中没有XPath解析功能,所以你需要使用第三方包。

我知道的一个包是Gokogiri
该包基于libxml2并使用cgo

你需要导入的子包是github.com/moovweb/gokogiri/xpath

英文:

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

答案3

得分: 9

即使不使用xpath,您也可以使用原生的go xml encoder包从XML中读取值。您可以使用xml.Unmarshal()函数。这里是一个go play的示例。

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)
}
英文:

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 &quot;fmt&quot;
import &quot;encoding/xml&quot;

func main() {
	type People struct {
		Names []string `xml:&quot;Person&gt;FullName&quot;`
	}
	
	data := `
		&lt;People&gt;
			&lt;Person&gt;
				&lt;FullName&gt;Jerome Anthony&lt;/FullName&gt;
			&lt;/Person&gt;
			&lt;Person&gt;
				&lt;FullName&gt;Christina&lt;/FullName&gt;
			&lt;/Person&gt;
		&lt;/People&gt;
	`
	
	v := People{Names: []string{}}
	err := xml.Unmarshal([]byte(data), &amp;v)
	if err != nil {
		fmt.Printf(&quot;error: %v&quot;, err)
		return
	}
	fmt.Printf(&quot;Names of people: %q&quot;, v)
}

答案4

得分: 6

xmlquery 允许您使用XPath表达式从XML文档中提取数据。

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())
}
英文:

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

package main

import (
    &quot;fmt&quot;
    &quot;strings&quot;
    &quot;github.com/antchfx/xmlquery&quot;
)

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

huangapple
  • 本文由 发表于 2012年11月16日 11:02:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/13409751.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定