An identity-constraint (unique/key/keyref) field that selects an absent attribute or an empty element whose declaration carries a default or fixed value now takes that value as its identity-tuple component, so two members can collide on the defaulted value (idG011/idG012 default, idF016/idF017 fixed) where the duplicate was previously missed. The default/fixed value constraints on identity-field targets are gathered at compile time (identityFieldConstraints, mirroring identityFieldTypes) and threaded through to the identity validator. The substitution is exact about absent versus present-empty: an @attr field is defaulted only when the attribute is ABSENT (an empty node-set), never when present with value ""; a "." element field only when the selected element has no character content. Applying a default only adds an identity value where the schema declares one, so it can create a genuine duplicate-key detection but never reject a valid instance. To keep within the file/type-size and one-type-per-file limits, FieldValue, XPathQueryCache, and the schema-location hints were extracted to their own files (behavior-preserving moves). invalid-instances-accepted 50 to 45, no false positive (valid-instances-rejected and valid-schemas-rejected held at 0), no other bucket moved. An adversarial review probed present-empty attributes, element content winning over a default, fixed values, keyref matching, multi-field keys, and merged-schema defaults, and found no over-rejection.
14 lines
556 B
Swift
14 lines
556 B
Swift
/// Compiles each distinct XPath string once per validation run, so a
|
|
/// constraint's selector and field queries are not re-parsed at every element
|
|
/// the walk visits. A string that fails to compile caches as nil (no match).
|
|
final class XPathQueryCache {
|
|
private var queries: [String: PureXML.XPath.Query?] = [:]
|
|
|
|
func query(_ xpath: String) -> PureXML.XPath.Query? {
|
|
if let cached = queries[xpath] { return cached }
|
|
let compiled = try? PureXML.XPath.Query(xpath)
|
|
queries[xpath] = compiled
|
|
return compiled
|
|
}
|
|
}
|