如何使用gokogiri(libxml2)使用命名空间解析xml?

时间:2014-12-14 21:19:28

标签: xml go libxml2

我使用github.com/moovweb/gokogiri来解析XML文档。以下在解析var b时起作用,但是当我在var a(具有命名空间)上尝试相同时,我得不到输出。如何使用gokogiri解析具有命名空间的XML?

package main

import (
    "github.com/moovweb/gokogiri"
    "github.com/moovweb/gokogiri/xpath"
    "log"
)

func main() {
    log.SetFlags(log.Lshortfile)
    doc, _ := gokogiri.ParseXml([]byte(a))
    defer doc.Free()
    doc.SetNamespace("", "http://example.com/this")
    x := xpath.Compile(".//NodeA/NodeB")
    groups, err := doc.Search(x)
    if err != nil {
        log.Println(err)
    }
    for i, group := range groups {
        log.Println(i, group)
    }
}

var a = `<?xml version="1.0" ?><NodeA xmlns="http://example.com/this"><NodeB>thisthat</NodeB></NodeA>`
var b = `<?xml version="1.0" ?><NodeA><NodeB>thisthat</NodeB></NodeA>`

编辑#1: 我也试过doc.RegisterNamespace但是

  

doc.RegisterNamespace undefined(type * xml.XmlDocument没有字段或方法RegisterNamespace)&#34;

x.RegisterNamespace获取

  

x.RegisterNamespace undefined(type * xpath.Expression没有字段或方法RegisterNamespace)&#34;

1 个答案:

答案 0 :(得分:7)

即使XML中使用的命名空间没有分配前缀(即默认值),您也需要注册一个并在xpath表达式中使用它。

此前缀可以是您喜欢的任何内容,我在这里使用ns。请注意,它可能与文档中使用的前缀(如果有)不同 - 需要匹配的重要部分是命名空间字符串本身。


实施例

package main

import (
    "fmt"
    "github.com/moovweb/gokogiri"
    "github.com/moovweb/gokogiri/xpath"
)

func main() {
    doc, _ := gokogiri.ParseXml([]byte(a))
    defer doc.Free()
    xp := doc.DocXPathCtx()
    xp.RegisterNamespace("ns", "http://example.com/this")
    x := xpath.Compile("/ns:NodeA/ns:NodeB")
    groups, err := doc.Search(x)
    if err != nil {
        fmt.Println(err)
    }
    for i, group := range groups {
        fmt.Println(i, group.Content())
    }
}

var a = `<?xml version="1.0" ?><NodeA xmlns="http://example.com/this"><NodeB>thisthat</NodeB></NodeA>`

输出:

0 thisthat