relaxng

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Aug 22, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package relaxng validates XML documents against RELAX NG schemas.

RELAX NG validates by a different model from XSD: a schema is a *pattern*, and validation computes the derivative of that pattern with respect to each item of input, accepting when what remains can match the empty sequence. That is why this is a separate engine rather than a use of the XSD automaton — there is no finite automaton to build, and interleave, which admits its branches in any order, is not something a Glushkov construction expresses.

The implementation follows James Clark's derivative algorithm, which is both the clearest description of the language and the one the conformance suite was written against.

Index

Constants

View Source
const DefaultMaxDepth = 1000

DefaultMaxDepth bounds validation recursion when MaxDepth is zero. It matches xdm.DefaultMaxDepth, so a document the parser accepts is one the validator will not refuse for depth alone.

View Source
const NS = "http://relaxng.org/ns/structure/1.0"

NS is the RELAX NG structure namespace.

Variables

This section is empty.

Functions

This section is empty.

Types

type Error

type Error struct {
	Path    string
	Message string
}

Error is one validity failure.

func (*Error) Error

func (e *Error) Error() string

type Options

type Options struct {
	// Resolver supplies the documents named by <externalRef> and <include>.
	// When nil, both are refused.
	Resolver Resolver
	// BaseURI is the location the schema itself was read from, against which
	// a relative href is resolved. It may be empty when the schema came from
	// somewhere with no location, in which case only absolute hrefs work.
	BaseURI string
}

Options configure compilation.

type Resolver

type Resolver interface {
	ResolveSchema(href string) (*xdm.Node, error)
}

Resolver fetches a schema document named by an <externalRef> or <include>.

It is an interface, and there is no default implementation, for the same reason DOCTYPE is refused by default and xsi:schemaLocation is ignored: an href in a schema is an instruction to go and read something, and where that read is allowed to reach is the caller's decision, not the schema author's. A caller that wants files supplies one that reads files; a caller that wants nothing supplies nothing, and every href is refused with an error that says so.

href is the value written in the schema, already resolved against the base URI in force — xml:base and the location the schema was loaded from — so an implementation receives one absolute reference rather than having to track the nesting itself.

type Schema

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

Schema is a compiled RELAX NG schema.

It is immutable once built and safe to share across goroutines, like a compiled XSD schema: validation takes derivatives of the pattern rather than mutating it.

func Compile

func Compile(doc *xdm.Node) (*Schema, error)

Compile builds a schema from a parsed RELAX NG document in the XML syntax.

The grammar is checked as it is read rather than afterwards: RELAX NG's restrictions are mostly about what may appear where — an attribute inside an attribute, a text inside a list — and catching those at the point of use gives an error that names the construct.

func CompileWithOptions

func CompileWithOptions(doc *xdm.Node, opts Options) (*Schema, error)

CompileWithOptions builds a schema, with a Resolver for <externalRef> and <include>.

Compile is this with no options, which refuses both. Splitting them keeps the safe thing the short thing to write: reaching outside the schema document is something a caller opts into, not something a schema can decide for itself.

func (*Schema) Validate

func (s *Schema) Validate(doc *xdm.Node) error

Validate checks a document against the schema.

The result is a single error rather than a list, which is the shape the derivative algorithm gives: a pattern that reaches notAllowedPat carries no record of the alternatives it tried, so there is one failure and it is the point at which every branch died. Reporting the *last* place the document was still viable is more useful than reporting the root.

func (*Schema) ValidateWithOptions

func (s *Schema) ValidateWithOptions(doc *xdm.Node, opts ValidateOptions) error

ValidateWithOptions checks a document, with limits on the run.

type ValidateOptions

type ValidateOptions struct {
	// MaxDepth bounds how deep validation will recurse. Zero means
	// DefaultMaxDepth; a negative value means no limit.
	//
	// This is not the parser's limit, and the distinction matters more here
	// than elsewhere: taking derivatives over a nested document costs time and
	// memory *quadratic* in the depth, since each level carries the pattern
	// remaining at every level above it. A tree can also be built by a
	// transform rather than parsed, and a caller who raises
	// xdm.ParseOptions.MaxDepth to accept a deep document has not thereby
	// agreed to let the validator spend a gigabyte on it.
	MaxDepth int
}

ValidateOptions bound one validation run.

Jump to

Keyboard shortcuts

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