【问题标题】:How do I parse xml with a namespace using gokogiri (libxml2)?如何使用 gokogiri (libxml2) 解析带有命名空间的 xml?
【发布时间】:2014-12-14 21:19:28
【问题描述】:

我正在使用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 has no field or method RegisterNamespace)"

x.RegisterNamespace得到

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

【问题讨论】:

  • 看看 func (xpath *XPath) RegisterNamespace(prefix, href string),可能在您查询 RegisterNamespace("NodeA", "example.com/this") 之前,奇迹发生了?
  • @user918176: 似乎无法弄清楚...doc.RegisterNamespace 和 x.RegisterNamespace 都返回错误
  • @user918176:我也尝试过 SetNameSpace("NodeA","example.com/this") 但这也不起作用...空切片...(例如... NodeA 不是前缀)

标签: xml go libxml2


【解决方案1】:

即使 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

【讨论】:

    猜你喜欢
    • 2019-03-17
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-01
    • 2012-06-09
    • 2010-09-12
    • 2014-07-28
    相关资源
    最近更新 更多