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 ¶
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.
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 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 ¶
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 ¶
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 ¶
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 ¶
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.