XSD 1.0 §3.11.4 (cvc-identity-constraint.3) requires each key/keyref/unique field to identify a node of simple type. A field that reaches an element declared with no type (the ur-type anyType) or an inline complex type without simple content does not, so the instance is invalid; the reference (libxml2) rejects it identically. PureXML accepted such instances because its identity validator could resolve a field target's type only for a global element reached by a direct-child name, not for a local element reached through a path (the W3C XSTS case idZ010 nests anyType fields several levels deep, e.g. a key field ./b/c where c has no type). A compile-time pass (XSDParser.identityNonSimpleFieldKeys) resolves each field's target element through its selector and field paths, by element-name steps, and records the fields whose declared target is provably non-simple. The validator rejects those at runtime unless the instance gives the node a simple type through xsi:type, since cvc reads the node's governing type (a text-only anyType element with xsi:type="xsd:int" is a valid field). The resolution is conservative: any wildcard, descendant axis, predicate, ref, or named non-builtin type leaves the field unflagged, so a valid field is never rejected. The one residual divergence path, two same-name child elements of differing simplicity in one inline model, is an Element-Declarations-Consistent violation the compiler already rejects. Verified over the full W3C XSTS corpus in release: invalid-instances-accepted 8 -> 7 (idZ010 now rejects), valid-instances-rejected held at 0 across all 14383 groups (no false positive), full suite (1837 tests), wasm, and lint all green. An adversarial critic that read every file and probed for a false positive could not construct one; the failure mode is under-rejection, the safe direction.
63 lines
3.6 KiB
Swift
63 lines
3.6 KiB
Swift
extension PureXML.Schema {
|
|
/// The result of compiling a schema document: its global element
|
|
/// declarations, its named-type table, and the identity constraints declared
|
|
/// on each element name.
|
|
struct XSDCompiled {
|
|
var elements: [String: ElementType]
|
|
var types: [String: ElementType]
|
|
var constraints: [String: [IdentityConstraint]]
|
|
/// Simple types for identity-constraint field paths.
|
|
var identityFieldTypes: [String: SimpleType] = [:]
|
|
/// `default`/`fixed` value constraints on identity-constraint field
|
|
/// targets, so an absent attribute or empty element takes that value as its
|
|
/// identity-tuple component.
|
|
var identityFieldConstraints: [String: ValueConstraint] = [:]
|
|
/// Identity fields whose declared target is not a simple type, so the field
|
|
/// violates cvc-identity-constraint.3 (idZ010).
|
|
var identityNonSimpleFields: Set<String> = []
|
|
/// Local names of elements declared `nillable="true"`.
|
|
var nillableElements: Set<String> = []
|
|
/// The `default`/`fixed` value constraint declared on each element name.
|
|
var elementConstraints: [String: ValueConstraint] = [:]
|
|
/// Local names of complex types declared `abstract="true"`. Bare-keyed, for
|
|
/// the schema-consistency rules and direct unit tests.
|
|
var abstractTypes: Set<String> = []
|
|
/// Local names of element declarations declared `abstract="true"`: they may
|
|
/// not appear in an instance directly, only through a substitution member.
|
|
var abstractElements: Set<String> = []
|
|
/// Derivation methods the named type forbids when used through `xsi:type`.
|
|
/// Bare-keyed.
|
|
var typeBlock: [String: Set<DerivationMethod>] = [:]
|
|
/// Derivation methods each element declaration forbids through `xsi:type`.
|
|
/// Bare-keyed.
|
|
var elementBlock: [String: Set<DerivationMethod>] = [:]
|
|
/// Each named complex type's base type and derivation method, the backbone
|
|
/// the schema-consistency rules walk. Bare-keyed.
|
|
var typeDerivation: [String: TypeDerivation] = [:]
|
|
/// Namespaced (`{ns}local`) views of the abstract-type set, `block` tables,
|
|
/// and derivation backbone, for the INSTANCE-validity subsystem, where two
|
|
/// imported types sharing a local name in different namespaces must not
|
|
/// collide.
|
|
var nsAbstractTypes: Set<String> = []
|
|
var nsTypeBlock: [String: Set<DerivationMethod>] = [:]
|
|
var nsElementBlock: [String: Set<DerivationMethod>] = [:]
|
|
var nsTypeDerivation: [String: TypeDerivation] = [:]
|
|
/// Each named union simple type's member type keys (`{ns}local`), so the
|
|
/// `xsi:type`-`block` check can follow a derivation that reaches the
|
|
/// declared union through one of its members (cos-st-derived-OK 2.2.4).
|
|
var nsUnionMembers: [String: [String]] = [:]
|
|
/// Derivation methods each named type declares `final`, for the
|
|
/// schema-consistency rules.
|
|
var typeFinal: [String: Set<DerivationMethod>] = [:]
|
|
/// The schema's target namespace, so the root element's namespace can be
|
|
/// checked against it.
|
|
var targetNamespace: String?
|
|
/// Schema-validity findings gathered while parsing (malformed facet
|
|
/// definitions and the like), reported together with the model-level
|
|
/// consistency findings when the schema is compiled.
|
|
var schemaErrors: [PureXML.Validation.ValidationError] = []
|
|
/// Global attribute declarations keyed by ``attributeDeclarationKey(_:)``.
|
|
var globalAttributes: [String: AttributeUse] = [:]
|
|
}
|
|
}
|