Skip to content

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"
    }
}