goxpath

package module
v1.0.12 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 1, 2026 License: BSD-3-Clause Imports: 25 Imported by: 6

README

goxpath

An XPath 3.1 evaluator written in Go — 85% W3C conformance (~19,000 of ~22,200 applicable QT3 tests passing).

Built on goxml for the XML tree model.

Features

  • Full XPath 3.1 expression language (let, for, if, arrow, maps, arrays, inline functions, dynamic calls)
  • 150+ XPath/XQuery functions including math, higher-order, JSON, date/time formatting
  • Typed numeric system (xs:double, xs:float, xs:decimal, xs:integer with subtype hierarchy)
  • Named function references, dynamic function calls, function-lookup
  • DecimalFormat API for customizable number formatting
  • Per-test regression detection against a W3C QT3 baseline

Usage

xp, _ := goxpath.NewParser(strings.NewReader(`<root><item id="1">Hello</item></root>`))
result, _ := xp.Evaluate("//item[@id='1']/text()")
fmt.Println(result) // [Hello]

See pkg.go.dev for the full Go API.

Testing

# Run all tests including W3C QT3 conformance (~2s)
git clone --depth 1 https://github.com/w3c/qt3tests.git testdata/qt3tests
go test ./...

# Update baseline after improvements
QT3_UPDATE_BASELINE=1 go test -run TestQT3Survey

The test suite compares each run against testdata/qt3_baseline.txt (~19,000 test names). Any regression is reported as a test failure with the specific test name.

Known Limitations

  • Regex back-references (\1, \2) are not supported (Go RE2 engine limitation)
  • Unicode Collation Algorithm (UCA): supported via golang.org/x/text/collate. lang, strength, numeric and fallback parameters are honored; caseFirst, caseLevel, alternate, maxVariable, reorder, backwards, version, normalization are accepted lax but not effectively applied (raise FOCH0002 with fallback=no).
  • Integer precision is limited to int64 (~9.2 × 10¹⁸); the spec requires arbitrary precision
  • Decimal is stored as float64 (~15-17 significant digits)
  • Timezone handling may add or omit timezone indicators in edge cases
  • Not implemented: fn:transform(), fn:idref(), namespace:: axis, schema-aware types

See the full limitations reference for details.

Documentation

Full reference at https://doc.speedata.de/goxml/ — includes language features, type system, all function categories, Go API, and known limitations.

License

BSD-3-Clause — see License.md.

Documentation

Index

Constants

View Source
const (
	CodepointCollationURI       = "http://www.w3.org/2005/xpath-functions/collation/codepoint"
	HTMLAsciiCaseInsensitiveURI = "http://www.w3.org/2005/xpath-functions/collation/html-ascii-case-insensitive"
	UCACollationURI             = "http://www.w3.org/2013/collation/UCA"
	UCACollationFallbackURI     = "http://www.w3.org/2013/collation/UCA/" // tolerated alias
)

Standard collation URIs defined by XPath 3.1 / XSLT 3.0.

Variables

View Source
var ErrConversion = fmt.Errorf("conversion failed")

ErrConversion is returned in case of an unsuccessful cast.

View Source
var ErrSequence = fmt.Errorf("a sequence with more than one item is not allowed here")

ErrSequence is raised when a sequence of items is not allowed as an argument.

Functions

func BooleanValue

func BooleanValue(s Sequence) (bool, error)

BooleanValue returns the effective boolean value of the sequence. XPath 2.0 §2.4.3: if the first item is a node, returns true; a single atomic value is converted to boolean; otherwise FORG0006.

func FunctionExists added in v1.0.10

func FunctionExists(namespace, name string) bool

FunctionExists returns true if a function with the given namespace and local name is registered.

func IntIsSubtypeOf added in v1.0.10

func IntIsSubtypeOf(child, ancestor IntSubtype) bool

IntIsSubtypeOf returns true if child is the same as or a subtype of ancestor.

func ItemStringvalue added in v1.0.6

func ItemStringvalue(itm Item) string

ItemStringvalue returns the string value of an individual item.

func NumberValue

func NumberValue(s Sequence) (float64, error)

NumberValue returns the sequence converted to a float.

func RegisterCollation added in v1.0.12

func RegisterCollation(uri string, factory CollationFactory)

RegisterCollation registers a collation factory for a given URI prefix. The most specific (longest) match wins. Pass an exact URI for parameter-less collations such as the codepoint collation.

func RegisterFunction

func RegisterFunction(f *Function)

RegisterFunction registers an XPath function

func StrIsSubtypeOf added in v1.0.10

func StrIsSubtypeOf(child, ancestor StrSubtype) bool

StrIsSubtypeOf returns true if child is the same as or a subtype of ancestor.

func StringValue

func StringValue(s Sequence) (string, error)

StringValue returns the string value of the sequence by concatenating the string values of each item.

func ToFloat64 added in v1.0.10

func ToFloat64(itm any) (float64, bool)

ToFloat64 extracts the float64 value from any numeric item. Returns the value and true if the item is numeric, or 0 and false otherwise.

func ToXSInteger

func ToXSInteger(itm Item) (int, error)

ToXSInteger converts the item to an xs:integer.

func TypeIDOf added in v1.0.10

func TypeIDOf(itm any) string

TypeIDOf returns the XPath type identifier for an item.

func XPathErrorCode added in v1.0.10

func XPathErrorCode(err error) (string, bool)

XPathErrorCode extracts the error code from an error, if it is an XPathError. Returns the code and true if successful, or empty string and false otherwise.

Types

type Collation added in v1.0.12

type Collation interface {
	// URI returns the canonical URI identifying this collation.
	URI() string
	// Compare returns -1, 0 or +1 like strings.Compare under this collation.
	Compare(a, b string) int
	// Equal reports whether the two strings are equal under this collation.
	Equal(a, b string) bool
	// Contains reports whether sub occurs as a (collation-equal) substring of s.
	Contains(s, sub string) bool
	// StartsWith reports whether s begins with prefix under this collation.
	StartsWith(s, prefix string) bool
	// EndsWith reports whether s ends with suffix under this collation.
	EndsWith(s, suffix string) bool
	// SubstringBefore returns the part of s before the first occurrence of sub,
	// or "" if sub does not occur in s. The empty sub returns "".
	SubstringBefore(s, sub string) string
	// SubstringAfter returns the part of s after the first occurrence of sub,
	// or "" if sub does not occur in s. The empty sub returns s.
	SubstringAfter(s, sub string) string
	// Key returns an opaque sort key suitable for use as a hash-map key.
	// Two strings are Equal iff their Keys are equal.
	Key(s string) string
}

Collation is a named string comparison rule used by XPath/XSLT functions such as fn:compare, fn:contains, xsl:sort etc.

All methods must be safe for concurrent use.

func CodepointCollation added in v1.0.12

func CodepointCollation() Collation

CodepointCollation returns the (cached) Unicode codepoint collation.

func ResolveCollation added in v1.0.12

func ResolveCollation(uri string) (Collation, error)

ResolveCollation looks up a collation by URI, instantiating it on demand. Returns FOCH0002 if the URI cannot be resolved.

type CollationFactory added in v1.0.12

type CollationFactory func(uri string, params url.Values) (Collation, error)

CollationFactory builds a Collation from URI parameters. The full URI is passed for round-tripping; params is the parsed query string.

type Context

type Context struct {
	Namespaces map[string]string // Storage for (private) name spaces
	Store      map[any]any       // Store can be used for private variables accessible in functions
	Pos        int               // Used to determine the position() in the sequence

	// DefaultCollation is the static default collation, used by string operators
	// and by string functions when no explicit collation argument is supplied.
	// If nil, the Unicode codepoint collation is used.
	DefaultCollation Collation
	// contains filtered or unexported fields
}

Context is needed for variables, namespaces and XML navigation.

func CopyContext

func CopyContext(cur *Context) *Context

CopyContext creates a new context with the underlying xml document but can be changed without changing the original context.

func NewContext

func NewContext(doc *goxml.XMLDocument) *Context

NewContext returns a context from the xml document

func (*Context) Attributes

func (ctx *Context) Attributes(tf testfuncAttributes) (Sequence, error)

Attributes returns all attributes of the current node that satisfy the testfunc

func (*Context) Collation added in v1.0.12

func (ctx *Context) Collation() Collation

Collation returns the static default collation, falling back to the Unicode codepoint collation if none is set.

func (*Context) Current

func (ctx *Context) Current(tf testfuncChildren) (Sequence, error)

Current returns all elements in the context that satisfy the testfunc.

func (*Context) CurrentItem added in v1.0.6

func (ctx *Context) CurrentItem() Item

CurrentItem returns the XSLT current() item.

func (*Context) CurrentTime added in v1.0.10

func (ctx *Context) CurrentTime() time.Time

CurrentTime returns the stable current time for this evaluation. Per XPath spec, current-dateTime() returns the same value within a single evaluation. The time is cached on first access and reused for all subsequent calls.

func (*Context) Document

func (ctx *Context) Document() goxml.XMLNode

Document moves the node navigator to the document and retuns it

func (*Context) Filter

func (ctx *Context) Filter(filter EvalFunc) (Sequence, error)

Filter applies predicates to the context

func (*Context) GetContextSequence

func (ctx *Context) GetContextSequence() Sequence

GetContextSequence returns the current context.

func (*Context) GetDecimalFormat added in v1.0.10

func (ctx *Context) GetDecimalFormat(name string) (*DecimalFormat, error)

GetDecimalFormat returns the decimal format with the given name. Returns the default format for name "". Returns nil and an error for unknown named formats (FODF1280).

func (*Context) ResetFrom added in v1.0.7

func (ctx *Context) ResetFrom(src *Context)

ResetFrom reuses an existing context by copying state from src. Unlike CopyContext, it reuses the existing map allocations instead of creating new maps, which reduces GC pressure in tight loops.

func (*Context) Root

func (ctx *Context) Root() (Sequence, error)

Root moves the node navigator to the root node of the document.

func (*Context) SetContextSequence

func (ctx *Context) SetContextSequence(seq Sequence) Sequence

SetContextSequence sets the context sequence and returns the previous one.

func (*Context) SetCurrentItem added in v1.0.6

func (ctx *Context) SetCurrentItem(item Item)

SetCurrentItem sets the XSLT current() item.

func (*Context) SetDecimalFormat added in v1.0.10

func (ctx *Context) SetDecimalFormat(name string, df *DecimalFormat)

SetDecimalFormat registers a named decimal format on the context. Use name "" for the default (unnamed) format. For qualified names, use "namespace-uri localname" as key.

func (*Context) SetSize added in v1.0.6

func (ctx *Context) SetSize(n int)

SetSize sets the context size used by last().

func (*Context) Size added in v1.0.6

func (ctx *Context) Size() int

Size returns the context size used by last().

type DecimalFormat added in v1.0.10

type DecimalFormat struct {
	DecimalSeparator  rune   // default '.'
	GroupingSeparator rune   // default ','
	MinusSign         rune   // default '-'
	Percent           rune   // default '%'
	PerMille          rune   // default '\u2030'
	ZeroDigit         rune   // default '0'
	Digit             rune   // default '#'
	PatternSeparator  rune   // default ';'
	Infinity          string // default "Infinity"
	NaN               string // default "NaN"
	ExponentSeparator rune   // default 'e'
}

DecimalFormat defines the properties of a decimal format as per XPath 3.1 / XSLT 3.0 (Section 4.7.1). Use DefaultDecimalFormat() to create an instance with spec-default values.

func DefaultDecimalFormat added in v1.0.10

func DefaultDecimalFormat() *DecimalFormat

DefaultDecimalFormat returns a DecimalFormat with the XPath spec-default values.

type EvalFunc

type EvalFunc func(*Context) (Sequence, error)

EvalFunc returns a sequence evaluating the XPath expression in the given context.

func ParseXPath

func ParseXPath(tl *Tokenlist) (EvalFunc, error)

ParseXPath takes a previously created token list and returns a function that can be used to evaluate the XPath expression in different contexts.

type Function

type Function struct {
	Name             string
	Namespace        string
	F                func(*Context, []Sequence) (Sequence, error)
	MinArg           int
	MaxArg           int
	DynamicCallError string // if non-empty, dynamic calls (via function reference) raise this error
}

Function represents an XPath function

type IntSubtype added in v1.0.10

type IntSubtype uint8

IntSubtype identifies the specific integer subtype in the XSD type hierarchy.

const (
	IntInteger            IntSubtype = iota // xs:integer
	IntLong                                 // xs:long
	IntInt                                  // xs:int
	IntShort                                // xs:short
	IntByte                                 // xs:byte
	IntNonNegativeInteger                   // xs:nonNegativeInteger
	IntUnsignedLong                         // xs:unsignedLong
	IntUnsignedInt                          // xs:unsignedInt
	IntUnsignedShort                        // xs:unsignedShort
	IntUnsignedByte                         // xs:unsignedByte
	IntPositiveInteger                      // xs:positiveInteger
	IntNonPositiveInteger                   // xs:nonPositiveInteger
	IntNegativeInteger                      // xs:negativeInteger
)

type Item

type Item any

An Item can hold anything such as a number, a string or a node.

func WrapNumeric added in v1.0.10

func WrapNumeric(val float64, nt NumericTypeID) Item

WrapNumeric wraps a float64 result in the appropriate numeric type.

type MapEntry added in v1.0.5

type MapEntry struct {
	Key   Item
	Value Sequence
}

MapEntry represents a key-value pair in an XPath map.

type NumericTypeID added in v1.0.10

type NumericTypeID int

NumericTypeID identifies the XPath numeric type of an item.

const (
	NumInteger NumericTypeID = iota
	NumDecimal
	NumFloat
	NumDouble
	NumUnknown
)

func NumericType added in v1.0.10

func NumericType(itm any) NumericTypeID

NumericType returns the numeric type ID for an item.

func PromoteNumeric added in v1.0.10

func PromoteNumeric(a, b NumericTypeID) NumericTypeID

PromoteNumeric returns the promoted type for a binary numeric operation. XPath type promotion: integer < decimal < float < double.

type Parser

type Parser struct {
	Ctx *Context
}

Parser contains all necessary references to the parser

func NewParser

func NewParser(r io.Reader) (*Parser, error)

NewParser returns a context to be filled

func (*Parser) Evaluate

func (xp *Parser) Evaluate(xpath string) (Sequence, error)

Evaluate reads an XPath expression and evaluates it in the given context. Parsed expressions are cached so that repeated evaluation of the same XPath string avoids re-tokenizing and re-parsing.

func (*Parser) SetVariable

func (xp *Parser) SetVariable(name string, value Sequence)

SetVariable is used to set a variable name.

func (*Parser) XMLDocument

func (xp *Parser) XMLDocument() *goxml.XMLDocument

XMLDocument returns the underlying XML document

type Sequence

type Sequence []Item

A Sequence is a list of Items

func (Sequence) IntValue

func (s Sequence) IntValue() (int, error)

IntValue returns the sequence value as an integer.

func (Sequence) String

func (s Sequence) String() string

func (Sequence) Stringvalue

func (s Sequence) Stringvalue() string

Stringvalue returns the concatenation of the string value of each item.

func (Sequence) StringvalueJoin added in v1.0.5

func (s Sequence) StringvalueJoin(sep string) string

StringvalueJoin returns the string values of all items joined by sep.

type StrSubtype added in v1.0.10

type StrSubtype uint8

StrSubtype identifies the specific string subtype in the XSD type hierarchy.

const (
	StrString           StrSubtype = iota // xs:string
	StrNormalizedString                   // xs:normalizedString
	StrToken                              // xs:token
	StrLanguage                           // xs:language
	StrNMTOKEN                            // xs:NMTOKEN
	StrName                               // xs:Name
	StrNCName                             // xs:NCName
	StrID                                 // xs:ID
	StrIDREF                              // xs:IDREF
	StrENTITY                             // xs:ENTITY
)

type Tokenlist

type Tokenlist struct {
	// contains filtered or unexported fields
}

Tokenlist represents units of XPath language elements.

type XPathArray added in v1.0.5

type XPathArray struct {
	Members []Sequence
}

XPathArray represents an XPath 3.1 array.

func (*XPathArray) Get added in v1.0.5

func (a *XPathArray) Get(pos int) (Sequence, error)

Get returns the member at the given 1-based index.

func (*XPathArray) Size added in v1.0.5

func (a *XPathArray) Size() int

Size returns the number of members in the array.

type XPathError added in v1.0.10

type XPathError struct {
	Code        string   // e.g. "XPTY0004", "FORG0001", "FOER0000"
	Description string   // human-readable description
	Value       Sequence // optional error value (for fn:error)
}

XPathError represents a structured XPath error with an error code, description, and optional error value. This implements the error interface and is used by try/catch expressions to match error codes.

func NewXPathError added in v1.0.10

func NewXPathError(code, description string) *XPathError

NewXPathError creates a new XPathError with the given code and description.

func (*XPathError) Error added in v1.0.10

func (e *XPathError) Error() string

Error implements the error interface.

type XPathFunction added in v1.0.10

type XPathFunction struct {
	Name             string
	Namespace        string
	Arity            int
	Fn               func(*Context, []Sequence) (Sequence, error)
	DynamicCallError string // if non-empty, calling this function reference raises this error
}

XPathFunction represents a callable function reference (XPath 3.1). Created by named function references (fn#arity) or inline functions.

func (*XPathFunction) Call added in v1.0.10

func (f *XPathFunction) Call(ctx *Context, args []Sequence) (Sequence, error)

Call invokes the function with the given arguments.

type XPathMap added in v1.0.5

type XPathMap struct {
	Entries []MapEntry
}

XPathMap represents an XPath 3.1 map.

func (*XPathMap) Contains added in v1.0.5

func (m *XPathMap) Contains(key Item) bool

Contains checks if a key exists in the map.

func (*XPathMap) Get added in v1.0.5

func (m *XPathMap) Get(key Item) (Sequence, bool)

Get looks up a key in the map by comparing string values.

func (*XPathMap) Keys added in v1.0.5

func (m *XPathMap) Keys() Sequence

Keys returns all keys in the map as a Sequence.

func (*XPathMap) Size added in v1.0.5

func (m *XPathMap) Size() int

Size returns the number of entries in the map.

type XSAnyURI added in v1.0.10

type XSAnyURI string

XSAnyURI represents an xs:anyURI value.

type XSBase64Binary added in v1.0.10

type XSBase64Binary string

XSBase64Binary represents an xs:base64Binary value.

type XSDate

type XSDate time.Time

XSDate is a date instance

func (XSDate) String

func (d XSDate) String() string

type XSDateTime

type XSDateTime time.Time

XSDateTime is a date time instance

func (XSDateTime) String

func (d XSDateTime) String() string

type XSDecimal added in v1.0.10

type XSDecimal float64

XSDecimal represents an xs:decimal value (no INF, no NaN).

type XSDouble added in v1.0.10

type XSDouble float64

XSDouble represents an xs:double value (IEEE 754 double precision).

type XSDuration added in v1.0.5

type XSDuration struct {
	Negative bool
	Years    int
	Months   int
	Days     int
	Hours    int
	Minutes  int
	Seconds  float64
}

XSDuration represents an xs:duration value with separate date and time components.

func ParseXSDuration added in v1.0.5

func ParseXSDuration(s string) (XSDuration, error)

ParseXSDuration parses an ISO 8601 duration string (e.g. "P1Y2M3DT4H5M6.5S", "-P1Y").

func (XSDuration) String added in v1.0.5

func (d XSDuration) String() string

type XSFloat added in v1.0.10

type XSFloat float64

XSFloat represents an xs:float value (IEEE 754 single precision, stored as float64).

type XSGDay added in v1.0.10

type XSGDay string

XSGDay represents xs:gDay.

type XSGMonth added in v1.0.10

type XSGMonth string

XSGMonth represents xs:gMonth.

type XSGMonthDay added in v1.0.10

type XSGMonthDay string

XSGMonthDay represents xs:gMonthDay.

type XSGYear added in v1.0.10

type XSGYear string

XSGYear represents xs:gYear.

type XSGYearMonth added in v1.0.10

type XSGYearMonth string

XSGYearMonth represents xs:gYearMonth.

type XSHexBinary added in v1.0.10

type XSHexBinary string

XSHexBinary represents an xs:hexBinary value (uppercase hex string).

type XSInteger added in v1.0.10

type XSInteger struct {
	V       int
	Subtype IntSubtype
}

XSInteger represents an xs:integer value with subtype information.

type XSQName added in v1.0.5

type XSQName struct {
	Namespace string
	Prefix    string
	Localname string
}

XSQName represents an xs:QName value with namespace URI, prefix, and local name.

func (XSQName) String added in v1.0.5

func (q XSQName) String() string

type XSString added in v1.0.10

type XSString struct {
	V       string
	Subtype StrSubtype
}

XSString represents an xs:string value with subtype information.

type XSTime

type XSTime time.Time

XSTime is a time instance

func (XSTime) String

func (d XSTime) String() string

type XSUntypedAtomic added in v1.0.10

type XSUntypedAtomic string

XSUntypedAtomic represents an xs:untypedAtomic value.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL