Schema-aware validator for DataModel
— catches structural defects (dangling references, missing types,
cyclic containment) and schema-level violations (unknown types,
forbidden type pairings, missing required property sets) and
surfaces them as a structured InspectionReport.
Same shape as
@xeokit/sdk/inspect/sceneModel —
pluggable inspections + a default registry — minus the auto-fix
half. No fixes ship for DataModel issues: SDK policy is to
surface defects in user data rather than silently rewrite it.
Triage is human work. Unlike geometry — where glitches
(degenerate triangles, duplicate vertices) are clearly mechanical
artefacts safe to clean up automatically — defects in the data
graph almost always reflect intentional or authoring-decision
content the application owner needs to see and decide on.
%%{init:{"theme":"dark"}}%%
flowchart LR
A[DataModel] --> B[inspectDataModel]
C[DataFormatSchema] --> B
B --> D[InspectionReport]
D -. errors block downstream optimisation .-> E[caller triages]
%%{init:{"theme":"default"}}%%
flowchart LR
A[DataModel] --> B[inspectDataModel]
C[DataFormatSchema] --> B
B --> D[InspectionReport]
D -. errors block downstream optimisation .-> E[caller triages]
flowchart LR
A[DataModel] --> B[inspectDataModel]
C[DataFormatSchema] --> B
B --> D[InspectionReport]
D -. errors block downstream optimisation .-> E[caller triages]
Features
Inspection-only — no auto-fix half. Defects surface as
issues; the caller decides how (and whether) to remediate.
Schema-aware — supply a DataFormatSchema and the
schema-tagged inspections fire (unknown types, forbidden type
pairings, required-property-set checks). Omit it and only the
schema-agnostic structural inspections run.
Schema segregation — each Inspection can declare
schemas: [...]; the orchestrator skips any inspection whose
schema list doesn't match the model's schema id. IFC-tagged
inspections only fire on IFC4 / IFC2x3 / IFC4x3 schemas.
Severity tiers — errors, warnings, info. Same
convention as sceneModel: errors block
downstream optimisation; warnings inform.
Opt-in expensive walks — cycle detection, schema-tagging
audits, IFC-specific hierarchy / containment checks are off by
default and enabled via checkX flags.
Async variant — inspectDataModelAsync yields to
the host periodically so very large data graphs don't block
the main thread.
Installation
npminstall@xeokit/sdk
Issue — one finding (severity, code, message,
resourceId, structured context).
InspectionReport — flat list plus per-severity and
per-code groupings.
Inspection — {codes[], description, run}. Walks
the DataModel and returns issues.
DataFormatSchema
The validator's rule book is a DataFormatSchema —
declarative spec listing allowed object types, allowed
relationship types, super-type chains for inheritance, and
per-type required / forbidden property sets. Pass one via
InspectDataModelParams.schema; omit it and only the
structural always-on inspections fire.
IFC_ELEMENT_AGGREGATED_NOT_CONTAINED (warning, opt-in via checkIfcElementContainment); IFC-only
Schema segregation
Each Inspection can declare a list of schema ids it applies to. The orchestrator resolves
the model's schema id (params.schema?.id ?? dataModel.schema)
and skips any inspection whose schemas list doesn't include
it. The IFC-tagged inspections only fire when the model's
schema id is one of IFC4 / IFC4x3 / IFC4X3 / IFC4x1 / IFC4X1 / IFC4_ADD2_TC1 / IFC2x3 / IFC2X3. Schema-agnostic inspections
leave schemas undefined and run regardless. A model with no
schema id at all (no dataModel.schema, no params.schema)
runs only the schema-agnostic inspections.
Dangling-reference checks (RELATIONSHIP_DANGLING_*,
OBJECT_DANGLING_PROPERTY_SET_REF) aren't included — DataModel's
builder methods reject unknown ids at construction time, so a
live DataModel can't carry dangling endpoints.
xeokit DataModel Inspector
Schema-aware validator for DataModel — catches structural defects (dangling references, missing types, cyclic containment) and schema-level violations (unknown types, forbidden type pairings, missing required property sets) and surfaces them as a structured InspectionReport.
Same shape as @xeokit/sdk/inspect/sceneModel — pluggable inspections + a default registry — minus the auto-fix half. No fixes ship for DataModel issues: SDK policy is to surface defects in user data rather than silently rewrite it. Triage is human work. Unlike geometry — where glitches (degenerate triangles, duplicate vertices) are clearly mechanical artefacts safe to clean up automatically — defects in the data graph almost always reflect intentional or authoring-decision content the application owner needs to see and decide on.
Shape
Pipeline
Features
schemas: [...]; the orchestrator skips any inspection whose schema list doesn't match the model's schema id. IFC-tagged inspections only fire on IFC4 / IFC2x3 / IFC4x3 schemas.errors,warnings,info. Same convention as sceneModel: errors block downstream optimisation; warnings inform.checkXflags.Installation
context).{codes[], description, run}. Walks the DataModel and returns issues.DataFormatSchema
The validator's rule book is a DataFormatSchema — declarative spec listing allowed object types, allowed relationship types, super-type chains for inheritance, and per-type required / forbidden property sets. Pass one via InspectDataModelParams.schema; omit it and only the structural always-on inspections fire.
Plug-in framework
Inspections are pluggable via InspectionRegistry. The SDK ships DEFAULT_INSPECTION_REGISTRY pre-loaded with the built-ins; plug-ins extend it on import:
Tests / one-off pipelines build a fresh InspectionRegistry and pass it via InspectDataModelParams.registry.
Built-in inspections
OBJECT_MISSING_TYPE(error),OBJECT_DUPLICATE_PROPERTY_SET_REF(warning)OBJECT_UNKNOWN_TYPE(error, when schema supplied)RELATIONSHIP_SELF_REFERENCE(warning)RELATIONSHIP_UNKNOWN_TYPE(error, when schema supplied)OBJECT_REQUIRED_PROPERTY_SET_MISSING/OBJECT_FORBIDDEN_PROPERTY_SET(warnings, when schema supplied)RELATIONSHIP_FORBIDDEN_RELATING_TYPE/RELATIONSHIP_FORBIDDEN_RELATED_TYPE/RELATIONSHIP_SELF_REFERENCE_FORBIDDEN(errors, opt-in viacheckRelationshipTypeBinding)OBJECT_SCHEMA_MISMATCH/RELATIONSHIP_SCHEMA_MISMATCH(warnings, opt-in viacheckSchemaTagging)RELATIONSHIP_CYCLE(error, opt-in viacheckRelationshipCycles)IFC_NO_PROJECT/IFC_MULTIPLE_PROJECTS/IFC_PROJECT_HAS_PARENT/IFC_SPATIAL_PARENT_TYPE_MISMATCH(errors),IFC_SPATIAL_ORPHAN(warning); opt-in viacheckIfcSpatialHierarchy; IFC-onlyIFC_ELEMENT_AGGREGATED_NOT_CONTAINED(warning, opt-in viacheckIfcElementContainment); IFC-onlySchema segregation
Each Inspection can declare a list of schema ids it applies to. The orchestrator resolves the model's schema id (
params.schema?.id ?? dataModel.schema) and skips any inspection whoseschemaslist doesn't include it. The IFC-tagged inspections only fire when the model's schema id is one ofIFC4 / IFC4x3 / IFC4X3 / IFC4x1 / IFC4X1 / IFC4_ADD2_TC1 / IFC2x3 / IFC2X3. Schema-agnostic inspections leaveschemasundefined and run regardless. A model with no schema id at all (nodataModel.schema, noparams.schema) runs only the schema-agnostic inspections.Dangling-reference checks (
RELATIONSHIP_DANGLING_*,OBJECT_DANGLING_PROPERTY_SET_REF) aren't included —DataModel's builder methods reject unknown ids at construction time, so a live DataModel can't carry dangling endpoints.