PureXML/Sources/Schema/IdentityConstraint.swift
Mihaela Mihaljevic fe19b0b1ea feat(xsd): add identity constraints (unique, key, keyref)
Validate XSD identity constraints over the instance document in a pass that
walks the tree alongside type validation:

- xs:unique requires the selected nodes' field tuples to be distinct, excluding
  any node that is missing a field.
- xs:key additionally requires every field to be present.
- xs:keyref requires each tuple to equal a tuple of the named key or unique
  visible in an enclosing scope, resolved through a stack of scope frames so a
  keyref and the key it refers to may sit on the same element.

The selector and field XPaths run on the existing XPath engine, relative to the
declaring element and each selected node. Constraints are gathered for every
element declaration at any depth, keyed by element name.

Closes #67
2026-06-08 08:58:36 +02:00

32 lines
1.3 KiB
Swift

public extension PureXML.Schema {
/// The kind of an ``IdentityConstraint``, and for a keyref the name of the
/// key it refers to.
enum IdentityConstraintKind: Sendable, Equatable {
/// Tuples must be distinct where present; a node missing a field is
/// excluded rather than rejected.
case unique
/// Tuples must be distinct and every field must be present.
case key
/// Every tuple must equal a tuple of the named key or unique in scope.
case keyref(refer: String)
}
/// An XSD identity constraint declared on an element: `xs:unique`, `xs:key`,
/// or `xs:keyref`. The `selector` XPath chooses the nodes the constraint
/// ranges over (relative to the declaring element), and each `field` XPath
/// extracts one component of the value tuple from a selected node.
struct IdentityConstraint: Sendable {
public var name: String
public var kind: IdentityConstraintKind
public var selector: String
public var fields: [String]
public init(name: String, kind: IdentityConstraintKind, selector: String, fields: [String]) {
self.name = name
self.kind = kind
self.selector = selector
self.fields = fields
}
}
}