Go API
Go API
Basic Usage
import "github.com/speedata/goxpath"
// Parse XML and evaluate XPath
xp, err := goxpath.NewParser(strings.NewReader(`<root><item>Hello</item></root>`))
if err != nil { log.Fatal(err) }
seq, err := xp.Evaluate(`/root/item/text()`)
if err != nil { log.Fatal(err) }
fmt.Println(seq) // [Hello]Variables
xp.SetVariable("price", goxpath.Sequence{42.0})
seq, _ := xp.Evaluate(`$price * 1.19`)Custom Functions
goxpath.RegisterFunction(&goxpath.Function{
Name: "greet",
Namespace: "http://example.com",
MinArg: 1,
MaxArg: 1,
F: func(ctx *goxpath.Context, args []goxpath.Sequence) (goxpath.Sequence, error) {
name, _ := goxpath.StringValue(args[0])
return goxpath.Sequence{"Hello, " + name + "!"}, nil
},
})Decimal Format API
Register custom decimal formats for format-number():
// Create a European decimal format
df := goxpath.DefaultDecimalFormat()
df.DecimalSeparator = ','
df.GroupingSeparator = '.'
df.MinusSign = '-'
df.NaN = "keine Zahl"
df.Infinity = "unendlich"
// Register on the context
xp.Ctx.SetDecimalFormat("european", df)
// Use in XPath
seq, _ := xp.Evaluate(`format-number(1234.5, '#.##0,00', 'european')`)
// Result: "1.234,50"DecimalFormat Properties
| Property | Default | Description |
|---|---|---|
DecimalSeparator |
. |
Separates integer and fraction |
GroupingSeparator |
, |
Groups digits |
MinusSign |
- |
Negative sign |
Percent |
% |
Percent marker (×100) |
PerMille |
‰ |
Per-mille marker (×1000) |
ZeroDigit |
0 |
Mandatory digit placeholder |
Digit |
# |
Optional digit placeholder |
PatternSeparator |
; |
Separates positive/negative sub-patterns |
Infinity |
"Infinity" |
String for infinite values |
NaN |
"NaN" |
String for not-a-number |
ExponentSeparator |
e |
Separates mantissa and exponent |
Type System
goxpath uses typed Go values for XPath types:
| XPath Type | Go Type |
|---|---|
xs:integer (and subtypes) |
goxpath.XSInteger{V int, Subtype IntSubtype} |
xs:double |
goxpath.XSDouble (float64) |
xs:float |
goxpath.XSFloat (float64) |
xs:decimal |
goxpath.XSDecimal (float64) |
xs:string (and subtypes) |
goxpath.XSString{V string, Subtype StrSubtype} |
xs:boolean |
bool |
xs:anyURI |
goxpath.XSAnyURI (string) |
xs:dateTime |
goxpath.XSDateTime (time.Time) |
xs:duration |
goxpath.XSDuration (struct) |
| Bare string literals | string |
| Bare integer literals | int |
| Decimal literals (3.14) | goxpath.XSDecimal |
| Double literals (3.14e0) | goxpath.XSDouble |
Helper Functions
// Extract float64 from any numeric type
f, ok := goxpath.ToFloat64(item)
// Get string value
s, err := goxpath.StringValue(seq)
// Get boolean value
b, err := goxpath.BooleanValue(seq)
// Get number value
n, err := goxpath.NumberValue(seq)Structured Errors
XPath errors include error codes for programmatic handling:
seq, err := xp.Evaluate(`xs:integer("abc")`)
if err != nil {
if xe, ok := err.(*goxpath.XPathError); ok {
fmt.Println(xe.Code) // "FORG0001"
fmt.Println(xe.Description) // "cannot cast \"abc\" to xs:integer"
}
}