PureXML/Sources/Schema/RelaxNGPattern.swift
Mihaela Mihaljevic 28cbed0a70 feat(relaxng): <param> facets under <data>
A <data type=> pattern now carries a SimpleType (base + facets) rather
than a bare built-in, and its <param name=>value</param> children
populate the facets (minLength, maxLength, length, pattern, min/max
inclusive/exclusive, total/fraction digits), reusing the XSD datatype
facet validation. So a constrained datatype like xsd:string with
minLength rejects too-short values.

datatypeLibrary resolution, typed <value> comparison, and the RNC
datatype parameter blocks remain.

Part of #79
2026-06-08 16:48:24 +02:00

43 lines
1.6 KiB
Swift

public extension PureXML.Schema {
/// A RELAX NG name class: which element or attribute names a pattern matches.
indirect enum NameClass: Sendable {
case anyName
case anyNameExcept(NameClass)
case name(namespace: String, localName: String)
case nsName(String)
case choice(NameClass, NameClass)
/// Whether `name` is in this class.
func contains(_ name: PureXML.Model.QualifiedName) -> Bool {
let namespace = name.namespaceURI ?? ""
switch self {
case .anyName: return true
case let .anyNameExcept(except): return !except.contains(name)
case let .name(wantedNamespace, wantedLocal): return namespace == wantedNamespace && name.localName == wantedLocal
case let .nsName(wantedNamespace): return namespace == wantedNamespace
case let .choice(left, right): return left.contains(name) || right.contains(name)
}
}
}
/// A RELAX NG pattern (the simplified algebra used by the derivative
/// algorithm). `optional`, `zeroOrMore`, and `mixed` are expressed through
/// these constructors; `after` is internal to derivation.
indirect enum Pattern: Sendable {
case empty
case notAllowed
case text
case choice(Pattern, Pattern)
case interleave(Pattern, Pattern)
case group(Pattern, Pattern)
case oneOrMore(Pattern)
case element(NameClass, Pattern)
case attribute(NameClass, Pattern)
case data(SimpleType)
case value(String)
case list(Pattern)
case ref(String)
case after(Pattern, Pattern)
}
}