A non-self-referencing model group redefined inside xs:redefine must be a valid
restriction of the group it redefines (cos-group-restrict / src-redefine 6.1.2),
so its content model may not widen the original's language. The check reuses the
particle-restriction oracle used for complex-type restriction, resolves the
original group by namespaced identity with a {}name chameleon fallback, and runs
post-compile where element type compatibility is available.
Now rejected: adding required content to an empty base (schZ006), dropping a
required all member (schL1), reordering an all (schL5/L6, the Recurse rule is
order-preserving even for all), growing to a superset (schL8), and the
multi-document/chained redefines schN4/5/6/7 and schL10. To stay
false-positive-free the check skips a redefinition carrying a self-reference and
declines to judge a base with a maxOccurs=0 pointless particle (the contested
case W3C accepts, mgO013); genuine restrictions (dropping an optional member, an
unchanged redefinition) are accepted.
XSTS invalid-schemas-accepted 64 -> 51, no false positive (valid-schemas-rejected
and valid-instances-rejected held at 0; an over-rejection of mgO013 surfaced by
the gate was fixed before commit, and an adversarial critic confirmed FP-safety),
no other bucket moved. Disclosed under-rejections: self-referencing redefinitions
(schN10) and maxOccurs=0-base redefines.
78 lines
4.4 KiB
Swift
78 lines
4.4 KiB
Swift
extension PureXML.Validation.SchemaCompile {
|
|
/// src-resolve: a resolved `include`/`import`/`redefine` `schemaLocation` (one the
|
|
/// loader returned content for) must be a well-formed schema document. The
|
|
/// failures are recorded on the context during composition; an unresolved
|
|
/// location (the loader returned nothing) is not recorded, since resolution is
|
|
/// the processor's choice.
|
|
static var referencedSchemasResolveToSchemas: PureXML.Validation.Validation<PureXML.Schema.SchemaCompileRoot, PureXML.Schema.SchemaCompileContext> {
|
|
compileRule("A resolved schemaLocation reference is a valid schema") { document in
|
|
PureXML.Schema.SchemaLocatedFinding.unlocated(
|
|
document.context.failedSchemaReferences.map {
|
|
"the referenced schema document '\($0)' is not a valid schema"
|
|
},
|
|
)
|
|
}
|
|
}
|
|
|
|
/// src-redefine.5: every type inside `xs:redefine` must restrict or extend the
|
|
/// type it redefines (same local name, in the redefining schema's own target
|
|
/// namespace).
|
|
static var redefinitionsDeriveFromThemselves: PureXML.Validation.Validation<PureXML.Schema.SchemaCompileRoot, PureXML.Schema.SchemaCompileContext> {
|
|
compileRule("A redefined type restricts or extends itself") { document in
|
|
PureXML.Schema.SchemaLocatedFinding.unlocated(
|
|
PureXML.Schema.XSDParser.redefineDerivationErrors(document.containers),
|
|
)
|
|
}
|
|
}
|
|
|
|
/// src-redefine.6.1/7.2.1: a redefined group or attribute group has at most one
|
|
/// self-reference, and a group self-reference occurs exactly once.
|
|
static var redefineSelfReferencesAreWellFormed: PureXML.Validation.Validation<PureXML.Schema.SchemaCompileRoot, PureXML.Schema.SchemaCompileContext> {
|
|
compileRule("A redefined group or attribute group has a well-formed self-reference") { document in
|
|
PureXML.Schema.SchemaLocatedFinding.unlocated(
|
|
PureXML.Schema.XSDParser.redefineSelfReferenceErrors(document.containers),
|
|
)
|
|
}
|
|
}
|
|
|
|
/// src-redefine: a redefinition of an attribute group restricts the original, so
|
|
/// it may not eliminate a required attribute use the original declares.
|
|
static var redefinedAttributeGroupsKeepRequired: PureXML.Validation.Validation<PureXML.Schema.SchemaCompileRoot, PureXML.Schema.SchemaCompileContext> {
|
|
compileRule("A redefined attribute group keeps the original's required attributes") { document in
|
|
PureXML.Schema.SchemaLocatedFinding.unlocated(
|
|
PureXML.Schema.XSDParser.redefineAttributeGroupRestrictionErrors(document.containers),
|
|
)
|
|
}
|
|
}
|
|
|
|
/// cos-group-restrict: a model group redefined through `xs:redefine` restricts the
|
|
/// original, so its content model must accept a subset of the original's. Reuses
|
|
/// the particle-restriction oracle; runs after named types resolve so element type
|
|
/// compatibility is available.
|
|
static var redefinedGroupsRestrictBase: PureXML.Validation.Validation<PureXML.Schema.SchemaCompileRoot, PureXML.Schema.SchemaCompileContext> {
|
|
compileRule("A redefined model group restricts the group it redefines") { document in
|
|
guard let namedTypes = document.namedTypes, let derivation = document.derivation else { return [] }
|
|
return PureXML.Schema.SchemaLocatedFinding.unlocated(
|
|
PureXML.Schema.XSDParser.redefineGroupRestrictionErrors(
|
|
document.containers,
|
|
context: document.context,
|
|
types: namedTypes,
|
|
derivation: derivation.typeDerivation,
|
|
),
|
|
)
|
|
}
|
|
}
|
|
|
|
/// Facet definition validity and pattern syntax validity (XSD Part 2 4.3): a
|
|
/// constraining facet must be applicable to and valid for its base type, and a
|
|
/// `pattern` must compile. These are gathered during simple-type compilation
|
|
/// (where the resolved base type is available) into the context's finding sink,
|
|
/// then surfaced here as a named, located validation rather than reported
|
|
/// straight to the diagnostics collector during parsing.
|
|
static var simpleTypeFacetsAreValid: PureXML.Validation.Validation<PureXML.Schema.SchemaCompileRoot, PureXML.Schema.SchemaCompileContext> {
|
|
compileRule("Simple-type facets are valid for their base type") { document in
|
|
document.context.facetFindingSink.findings
|
|
}
|
|
}
|
|
}
|