How to parse xml with namespace using gokogiri (libxml2)?

I am using github.com/moovweb/gokogiri

to parse an XML document. The parsing var b

does the following: but when I try to do the same on var a

(which has a namespace), I get no output. How do I process XML that has a namespace using gokogiri

?

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>`

      

EDIT # 1: I also tried doc.RegisterNamespace

but got

doc.RegisterNamespace undefined (type * xml.XmlDocument has no RegisterNamespace field or method) "

and x.RegisterNamespace

getting

x.RegisterNamespace undefined (type * xpath.Expression does not have a RegisterNamespace field or method) "

+3


source to share


1 answer


Even though the namespace used in XML has no prefix (i.e. the default), you need to register and use it in your xpath expression.

This prefix can be anything I used here ns

. Note that this may differ from the prefix used in the document (if any) - the important part that must match is the namespace string itself.


Example:



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>`

      


Output:

0 thisthat

      

+5


source







All Articles