Particle Valid (Restriction) was keyed by type name, so an inline complexType
deriving by complexContent restriction was never checked against its base. Such
anonymous restrictions are now compiled and run through the same subset
algorithm as named types.
XSTS invalid-schemas-accepted 163 to 148, no other bucket moved.
Particle Valid (Restriction) now requires a restricting element's {disallowed
substitutions} to be a superset of the base element's: a restriction may block
more substitutions, never fewer. The element particle (Term.element) carries a
block set, populated from the element's block attribute or the schema's
blockDefault.
XSTS invalid-schemas-accepted 179 to 163, no other bucket moved.
An element restricting a base model group is treated as a synthetic group with
minOccurs=maxOccurs=1 holding the element (XSD 1.0 sec 3.9.6), so its {1,1}
occurrence must be within the base group's range: a base group that must occur
two or more times cannot be restricted to a single element. The element's own
occurrence is still matched against the base branch it maps to, so an optional
element restricting a once-or-more base group stays valid.
XSTS invalid-schemas-accepted 181 to 179, no other bucket moved.
A redefine may redefine a given component at most once (src-redefine.7.2.2);
two redefinitions of the same kind and name in one redefine are invalid.
XSTS invalid-schemas-accepted 182 to 181, no other bucket moved.
Once the redefined document is loaded through a schemaLoader, every component a
redefine names (complexType, simpleType, group, attributeGroup) must have a
same-kind component of the same name in the redefined schema (src-redefine.6 /
7.2.1). A redefinition of a component that does not exist there is rejected; a
stand-alone schema (target not loaded) is unaffected.
XSTS invalid-schemas-accepted 183 to 182, no other bucket moved.
An element or attribute default/fixed value is now validated against an inline
type (an inline simpleType, or an inline complex type with simpleContent) the
same way it already was against a named type reference. Validated against the
simpleContent base's value space, so only a clear value-space mismatch (a
non-numeric default on a decimal-based type) is flagged.
XSTS invalid-schemas-accepted 185 to 183, no other bucket moved.
A complex type without its own final attribute now inherits the schema's
finalDefault as its {final}, so finalDefault=#all or restriction/extension
blocks a complexContent restriction or extension derived from it. An explicit
final= overrides the default to empty. Complex types previously honoured only
an explicit final (elements already inherited finalDefault).
XSTS invalid-schemas-accepted 189 to 185, no other bucket moved.
A local element declaration (an element particle, not a direct child of schema)
may not carry abstract, final, or substitutionGroup, which belong to the
top-level element form only. Their presence is invalid at any value, so
abstract=false on a local element is rejected as well as abstract=true.
XSTS invalid-schemas-accepted 194 to 189, no other bucket moved.
A complexContent extension that explicitly states mixed must match its base
type's mixedness (cos-ct-extends.1.4.3.2.2.1): a mixed extension extends only a
mixed base, an element-only extension only an element-only base. An extension
that omits mixed inherits the base's setting and stays valid, so only an
explicit conflict is rejected (ctZ012b, which inherits, is not flagged).
XSTS invalid-schemas-accepted 197 to 194, no other bucket moved.
A complexContent or simpleContent's content model requires exactly one
restriction or extension. An empty <complexContent/> declares no derivation
and is now rejected as a structural error.
XSTS invalid-schemas-accepted 200 to 197, no other bucket moved.
A \p{...}/\P{...} property name that can be no XSD charProp under any
repertoire (empty, the bare prefix Is, a non-block name carrying a non-letter,
or Is followed by a non-block character) is now a schema-validity error,
distinct from a well-formed but unrecognised category or block name, which
stays a lenient engine limitation.
XSTS invalid-schemas-accepted 203 to 200, no other bucket moved.
An attribute ref is a use of a global declaration, so it may not also carry
form (src-attribute.3.2). And no attribute declaration may be named xmlns,
which is reserved for namespace declarations (no-xmlns).
XSTS invalid-schemas-accepted 207 to 203, no other bucket moved.
A referencing attributeGroup (one with a ref) names a definition elsewhere; its
own content model is (annotation?), so it may not also declare attributes,
nested attributeGroup references, or an anyAttribute. Only a defining
attributeGroup (with a name) carries those.
XSTS invalid-schemas-accepted 210 to 207, no other bucket moved.
A notation declaration occupies its own symbol space, so two notations sharing
a name and target namespace are a duplicate just as two global types or
elements would be. Notations were omitted from the uniqueness check.
XSTS invalid-schemas-accepted 211 to 210, no other bucket moved.
A notation declaration's content model is (annotation?): it may carry only an
optional annotation child. Any other element child, or any non-whitespace
character content, is now rejected.
XSTS invalid-schemas-accepted 214 to 211, no other bucket moved.
A list simple type must draw its item type from exactly one of an itemType
attribute or an inline simpleType child; neither, or both, is invalid. A union
must declare at least one member type through a memberTypes attribute or an
inline simpleType child; an empty union declares none (src-simple-type.2/.3).
XSTS invalid-schemas-accepted 215 to 214, no other bucket moved.
A simple type that declares no `final` of its own takes the schema's
`finalDefault` as its `{final}` property (XSD 1.0 Schemas section 3.14.2). The
list and union derivation checks read the `final` attribute directly but
ignored `finalDefault`, so `finalDefault="list"` or `"union"` did not block a
list item type or union member type and the schema was wrongly accepted.
The final map now falls back to `finalDefault` for a type without its own
`final`; an explicit `final=""` still overrides the default back to no
restriction, and a built-in item or member type stays unaffected (it is matched
only when the reference resolves to the schema's own namespace).
Caught two invalid schemas: XSTS invalid-schemas-accepted 217 -> 215, no other
bucket moved.
A `pattern` facet's value must be a valid XSD regular expression. Two
truncation cases were compiled with a non-rejecting error and the schema was
wrongly accepted:
- a trailing `\` with no character to escape (`a\`), and
- a `[` character class the expression ends before closing with `]`
(`a[`, `[a[:xyz:`).
Both are unambiguously invalid, never an engine limitation on an otherwise
valid pattern, so they now raise the dedicated `RegexError.incompleteEscape`
and `RegexError.unterminatedClass` and `rejectsPattern` treats them as
schema-validity errors. A completed escape (`\[`, `\\`), a closed class, and a
class containing an escaped `]` or a subtraction stay valid.
Caught thirteen invalid schemas: XSTS invalid-schemas-accepted 230 -> 217, no
other bucket moved.
An attribute use that references a global attribute carrying a `fixed` value
constraint may not contradict it (au-props-correct.2): a `fixed` on the
reference whose value differs from the global's, or a `default` on a reference
to a fixed attribute, is invalid. A reference that omits its own value
constraint inherits the global's and stays valid.
The two `fixed` values are compared in the attribute type's value space, so a
value-equal pair written in different lexical forms (`01` for `1`) is not
flagged. The global is resolved by local name and only checked once its own
namespace matches the reference's resolved namespace, so a same-local-name
attribute imported from another namespace cannot surface as the wrong global
and contradict a valid reference.
Caught two invalid schemas: XSTS invalid-schemas-accepted 232 -> 230, no other
bucket moved.
Extending a complexType whose whole content is a non-empty xs:all group, via
complexContent extension that adds element content, nests that all in the
sequence joining base and extension content, which cos-all-limited forbids
(an all group must be the whole content model). Such schemas were accepted.
This is the symmetric companion to the existing rule (an all group in the
extension over a base with content); both now live in one pass. An empty-all
base contributes no content, and an attribute-only extension adds none, so
both stay valid.
XSTS invalid-schemas-accepted 233 to 232, no other bucket moved.
A complexContent extension that adds element content (a non-empty model
group) produces an element-only/mixed content type, so its base must have
complex or empty content, not simpleContent (cos-ct-extends.1.4.2.2). Such
schemas were accepted.
The check requires the extension to add actual element content (an element or
wildcard, not an empty group), so an attribute-only complexContent extension
of a simpleContent base stays valid (the complexContent-around-simpleContent
idiom, e.g. particlesZ031).
XSTS invalid-schemas-accepted 235 to 233, no other bucket moved.
Two schema-for-schemas structural constraints were not enforced, so the
malformed schemas were accepted:
- The compositor of a top-level named xs:group (all/choice/sequence) may not
carry minOccurs/maxOccurs; those belong on a group reference, not the
definition.
- An attribute in the XML Schema namespace (e.g. xsd:type) is never valid on a
schema element, since the vocabulary defines no namespaced attributes. A
foreign attribute in any other namespace stays the author's own.
XSTS invalid-schemas-accepted 244 to 235, no other bucket moved. (A third
candidate, form on a top-level declaration, was already enforced by the
existing top-level attribute rule, so no new check was needed.)
A pattern facet with an unambiguously malformed regular expression was
compiled leniently and the schema accepted. Three such constructs are now
rejected: a reversed character-class range ([b-a]), an empty class ([]),
and a reversed bounded quantifier ({37,17}). The parser raises distinct
RegexError cases (reversedRange, emptyClass, reversedQuantifier) that the
schema-validity check treats as invalid.
Constructs the engine merely does not support (an untabulated \p{Is...}
block, the lenient {,m} form) stay non-rejecting, so a valid pattern is
never refused. XSTS invalid-schemas-accepted 262 to 244, no other bucket
moved; the 27 regex unit tests still pass.
An identity-constraint attribute field's type was resolved only among the
constraint host's descendant elements, so when the selector targets a global
element referenced from the host (e.g. unique over `.//uid` with field
`@val`), the field type was unknown and values compared lexically. Two keys
equal in value space but not lexically (3.0 and 3 for xsd:decimal) were then
treated as distinct and the duplicate was accepted.
The attribute type now resolves through the selector's target global element,
so values compare in their value space. XSTS invalid-instances-accepted
133 to 132 (idF010), no other bucket moved.
Identity-constraint selector and field XPath prefixes were resolved against
the instance document's namespace bindings, so a constraint declared with
xmlns:v="..." and a selector like .//v:vehicle matched nothing when the
instance used a default namespace instead of the v prefix. The selector then
selected no nodes, no key tuples were collected, and duplicate-key and
keyref violations went undetected.
Prefixes now resolve against the namespace bindings in scope where the
constraint is declared in the schema (XSD Part 1, Identity-constraint
Definition), captured at parse time onto IdentityConstraint. A QName field
value still compares using the instance's bindings, so QName keys are
unaffected.
XSTS invalid-instances-accepted 143 to 133: the idc004/5/6 namespaced
key/keyref cluster and namespace-resolution cases (idZ010 and kin), no other
bucket moved.
An identity-constraint field must evaluate to a node-set with at most one
member (cvc-identity-constraint.3). The validator built a value tuple per
target without checking how many nodes each field selected, so an instance
whose unique/key/keyref field matched several nodes was accepted.
fieldCardinalityError now rejects a target whose field selects more than one
node, in both the key/unique and keyref paths. XSTS invalid-instances-accepted
4 → fewer (147 to 143), no other bucket moved.
Schema documents that form an import chain are now compiled as a single
union (Document.init(composing:)) rather than as separately compiled
documents merged after the fact. Merging froze each document's content
models with only the substitution-group members visible in its own import
closure, so a substitution member declared in an importing document never
reached the head's content model in the imported document.
This clears XSTS ctZ007, a cross-document substitution group, taking
valid-instances-rejected (#146) from 4 to 3 with no other bucket moving
(now 1/262/3/147). The union pools each document's container closure into
one context, deduplicating a document supplied directly and also reached
through another's import by target namespace and component-name set.
The XSTS runner uses the union only for import chains, detected by matching
import/include/redefine schemaLocation basenames against the listed
documents; independent roots stay on the lenient per-document merge, which a
union would wrongly trip with cross-document checks.
The remaining three valid-instance rejections are the Ethiopic-digit \d
cases (reS17, reS38, reZ004v), which contradict \d = \p{Nd}.
Consolidates the in-progress #146 work; valid-instances-rejected reaches 4
on the 2006-11-06 XSTS archive (buckets now 1/262/4/147).
Regex: match Unicode scalars rather than grapheme clusters; the empty
pattern matches only the empty string; pin the category repertoire to
Unicode 3.2, the version the corpus is consistent at, so code points added
in 3.2 (Tagalog, Cyrillic Komi) are word characters while later additions
(the Tamil digit zero) stay unassigned and match \D. New XSDCategory and a
3.2 assignment table derived from DerivedAge, replacing the old Unicode31
files.
Content model: assess each child against the particle the content automaton
matched, not a by-name lookup (#180). Two same-named particles keep their
own fixed values, and an element matching a skip wildcard is no longer
validated against its global declaration. Selection is made reproducible
when an ambiguous schema slips past the UPA check.
XSTS runner: compile and merge every schemaDocument in a schemaTest, not
just the first; this also surfaced one previously-masked invalid-instance
acceptance (recorded in the baselines).
Also folds in attribute-group anyAttribute inheritance, extension wildcard
union, namespace-qualified type tables for multi-document
xsi:schemaLocation, per-container elementFormDefault, strict and lax
attribute wildcard validation, built-in type resolution, and xs:redefine
simpleType overrides.
Schema compile findings now carry ValidationError coding paths that resolve to source spans on a ranged tree, enabling IDE underlines for id, structure, include, and facet violations.
Ship the OpenAPIKit-style validation layer (builtin rules, warnings channel,
Validator tiers, coverage gates) and wire XSD compile checks through it. Advance
#161 with chameleon include validation, multi-container reference resolution,
and include targetNamespace composition rules so merged schema sets compile
correctly when a schemaLoader is provided.
Cut the second pre-release: schema-validity burn-down to XSTS baselines
1/266/171/155, component child-content shape checks, and synced conformance
docs. CHANGELOG updated for v0.2.0.
Require that any restricted attribute has a type validly derived by restriction from its base counterpart. Validates atomic built-in derivation, list item type restrictions, and union member/subset relationships recursively. Updates baseline to 362 accepted invalid schemas.
Reject top level declarations that omit a name attribute. Disallow derivation by restriction of xs:anySimpleType inside simpleType definitions. Require restriction facets length, minLength, maxLength, totalDigits, and fractionDigits to restrict or equal the base type facets. Updates the conformance baseline to 383 accepted invalid schemas.