With cxpath you can access XML files via XPath 2.0 in a Go friendly matter.
<a:rootxmlns:a="anamespace">
<a:sub>text</a:sub>
</a:root>package main
import (
"fmt""log""github.com/speedata/cxpath"
)
funcdothings() error {
ctx, err:=cxpath.NewFromFile("myfile.xml")
iferr!=nil {
returnerr
}
// for XPath queriesctx.SetNamespace("a", "anamespace")
root:=ctx.Root()
// prints 'root'fmt.Println(root.Eval("local-name()"))
// prints subfmt.Println(root.Eval("local-name(a:sub)"))
// prints anamespacefmt.Println(root.Eval("namespace-uri(a:sub)"))
sub:=root.Eval("a:sub")
forcp:=rangesub.Each("string-to-codepoints(.)") {
// prints 116, 101, 120, 116 - the codepoints for 'text'fmt.Println(cp)
}
returnnil
}
funcmain() {
iferr:=dothings(); err!=nil {
log.Fatal(err)
}
}The constructors NewFromFile and NewFromReader return errors the usual Go way.
For all other methods, errors are stored in the Error field of the returned Context so that method chaining stays clean:
root:=ctx.Root()
result:=root.Eval("some/xpath")
ifresult.Error!=nil {
log.Fatal(result.Error)
}
fmt.Println(result.String())The same applies to the Each iterator. If the XPath expression is invalid, the iterator yields a single Context with the Error field set:
foritem:=rangeroot.Each("some/xpath") {
ifitem.Error!=nil {
log.Fatal(item.Error)
}
fmt.Println(item.Int())
}The value accessors Int() and Bool() also store conversion errors in Context.Error rather than returning them directly.
go get github.com/speedata/cxpath