Skip to content

Repository files navigation

go-libxml2

Build Status

GoDoc

Interface to libxml2, with DOM interface.

Why?

I needed to write go-xmlsec. This means we need to build trees using libxml2, and then muck with it in xmlsec: Two separate packages in Go means we cannot (safely) pass around C.xmlFooPtr objects (also, you pay a penalty for pointer types). This package carefully avoid references to C.xmlFooPtr types and uses uintptr to pass data around, so other libraries that needs to interact with libxml2 can safely interact with it.

Status

  • This library should be considered alpha grade. API may still change.
  • Much of commonly used functionalities from libxml2 that I use are there already, and are known to be functional

Package Layout:

NameDescription
libxml2Globally available utility functions, such as ParseString
typesCommon data types, such as types.Node
parserParser routines
domDOM-like manipulation of XML document/nodes
xpathXPath related tools
xsdXML Schema related tools
clibWrapper around C libxml2 library - DO NOT TOUCH IF UNSURE

Features

Create XML documents using DOM-like interface:

d:=dom.CreateDocument()
e, err:=d.CreateElement("foo")
iferr!=nil {
println(err)
return
}
d.SetDocumentElement(e)
...

Parse documents:

d, err:=libxml2.ParseString(xmlstring)
iferr!=nil {
println(err)
return
}

Use XPath to extract node values:

text:=xpath.String(node.Find("//xpath/expression"))

Examples

Basic XML Example

import (
"log""net/http""github.com/lestrrat/go-libxml2""github.com/lestrrat/go-libxml2/parser""github.com/lestrrat/go-libxml2/types""github.com/lestrrat/go-libxml2/xpath"
)
funcExampleXML() {
res, err:=http.Get("http://blog.golang.org/feed.atom")
iferr!=nil {
panic("failed to get blog.golang.org: "+err.Error())
}
p:=parser.New()
doc, err:=p.ParseReader(res.Body)
deferres.Body.Close()
iferr!=nil {
panic("failed to parse XML: "+err.Error())
}
deferdoc.Free()
doc.Walk(func(n types.Node) error {
log.Printf(n.NodeName())
returnnil
})
root, err:=doc.DocumentElement()
iferr!=nil {
log.Printf("Failed to fetch document element: %s", err)
return
}
ctx, err:=xpath.NewContext(root)
iferr!=nil {
log.Printf("Failed to create xpath context: %s", err)
return
}
deferctx.Free()
ctx.RegisterNS("atom", "http://www.w3.org/2005/Atom")
title:=xpath.String(ctx.Find("/atom:feed/atom:title/text()"))
log.Printf("feed title = %s", title)
}

Basic HTML Example

funcExampleHTML() {
res, err:=http.Get("http://golang.org")
iferr!=nil {
panic("failed to get golang.org: "+err.Error())
}
doc, err:=libxml2.ParseHTMLReader(res.Body)
iferr!=nil {
panic("failed to parse HTML: "+err.Error())
}
deferdoc.Free()
doc.Walk(func(n types.Node) error {
log.Printf(n.NodeName())
returnnil
})
nodes:=xpath.NodeList(doc.Find(`//div[@id="menu"]/a`))
fori:=0; i<len(nodes); i++ {
log.Printf("Found node: %s", nodes[i].NodeName())
}
}

XSD Validation

import (
"io/ioutil""log""os""path/filepath""github.com/lestrrat/go-libxml2""github.com/lestrrat/go-libxml2/xsd"
)
funcExampleXSD() {
xsdfile:=filepath.Join("test", "xmldsig-core-schema.xsd")
f, err:=os.Open(xsdfile)
iferr!=nil {
log.Printf("failed to open file: %s", err)
return
}
deferf.Close()
buf, err:=ioutil.ReadAll(f)
iferr!=nil {
log.Printf("failed to read file: %s", err)
return
}
s, err:=xsd.Parse(buf)
iferr!=nil {
log.Printf("failed to parse XSD: %s", err)
return
}
defers.Free()
d, err:=libxml2.ParseString(`<foo></foo>`)
iferr!=nil {
log.Printf("failed to parse XML: %s", err)
return
}
iferr:=s.Validate(d); err!=nil {
for_, e:=rangeerr.(xsd.SchemaValidationError).Errors() {
log.Printf("error: %s", e.Error())
}
return
}
log.Printf("validation successful!")
}

Caveats

Other libraries

There exists many similar libraries. I want speed, I want DOM, and I want XPath.When all of these are met, I'd be happy to switch to another library.

For now my closest contender was xmlpath, but as of this writing it suffers in the speed (for xpath) area a bit:

shoebill% go test -v -run=none -benchmem -benchtime=5s -bench .
PASS
BenchmarkXmlpathXmlpath-4 500000 11737 ns/op 721 B/op 6 allocs/op
BenchmarkLibxml2Xmlpath-4 1000000 7627 ns/op 368 B/op 15 allocs/op
BenchmarkEncodingXMLDOM-4 2000000 4079 ns/op 4560 B/op 9 allocs/op
BenchmarkLibxml2DOM-4 1000000 11454 ns/op 264 B/op 7 allocs/op
ok github.com/lestrrat/go-libxml2 37.597s

See Also

Credits

About

Interface to libxml2, with DOM interface

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages