dongxidui1227 2014-12-14 21:19
浏览 51
已采纳

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

I am using github.com/moovweb/gokogiri to parse an XML document. The following works when parsing var b but when I try the same on var a (which has a namespace) I get no output. How do I parse 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've also tried doc.RegisterNamespace but got

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

and x.RegisterNamespace getting

x.RegisterNamespace undefined (type *xpath.Expression has no field or method RegisterNamespace)"

  • 写回答

1条回答 默认 最新

  • dongxing4196 2014-12-14 23:12
    关注

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

    This prefix can be anything you like, here I used ns. Note it can be different from the prefix used in the document (if any) - the important part that needs to 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
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 ansys fluent计算闪退
  • ¥15 有关wireshark抓包的问题
  • ¥15 Ubuntu20.04无法连接GitHub
  • ¥15 需要写计算过程,不要写代码,求解答,数据都在图上
  • ¥15 向数据表用newid方式插入GUID问题
  • ¥15 multisim电路设计
  • ¥20 用keil,写代码解决两个问题,用库函数
  • ¥50 ID中开关量采样信号通道、以及程序流程的设计
  • ¥15 U-Mamba/nnunetv2固定随机数种子
  • ¥30 C++行情软件的tick数据如何高效的合成K线