@@ -72,13 +72,15 @@ class JSONStructureSchemaCoreValidator:
7272 "JSONStructureConditionalComposition" , "JSONStructureValidation"
7373 }
7474
75- def __init__ (self , allow_dollar = False , allow_import = False , import_map = None , extended = False ):
75+ def __init__ (self , allow_dollar = False , allow_import = False , import_map = None , extended = False , external_schemas = None ):
7676 """
7777 Initializes a validator instance.
7878 :param allow_dollar: Boolean flag to allow '$' in property names.
7979 :param allow_import: Boolean flag to enable processing of $import/$importdefs.
8080 :param import_map: Dictionary mapping URI to local filenames.
8181 :param extended: Boolean flag to enable extended validation features.
82+ :param external_schemas: List of schema dicts to use for resolving imports by $id.
83+ Each schema should have a '$id' field matching the import URI.
8284 """
8385 self .errors = []
8486 self .doc = None
@@ -87,6 +89,12 @@ def __init__(self, allow_dollar=False, allow_import=False, import_map=None, exte
8789 self .import_map = import_map if import_map is not None else {}
8890 self .extended = extended
8991 self .enabled_extensions = set ()
92+ # Build lookup for external schemas by $id
93+ self .external_schemas = {}
94+ if external_schemas :
95+ for schema in external_schemas :
96+ if isinstance (schema , dict ) and "$id" in schema :
97+ self .external_schemas [schema ["$id" ]] = schema
9098 if allow_dollar :
9199 self .identifier_regex = re .compile (r'^[A-Za-z_$][A-Za-z0-9_$]*$' )
92100 else :
@@ -289,51 +297,23 @@ def _process_imports(self, obj, path):
289297 def _fetch_external_schema (self , uri ):
290298 """
291299 Fetches an external schema from a URI.
292- If a mapping is provided and contains the URI, loads from the given file.
293- Otherwise, uses a simulated lookup.
294- """
300+ Resolution order:
301+ 1. Check external_schemas (pre-loaded schemas matched by $id)
302+ 2. Check import_map (URI to file path mapping)
303+ """
304+ # First check sideloaded schemas by $id
305+ if uri in self .external_schemas :
306+ return self .external_schemas [uri ]
307+ # Then check import_map for file paths
295308 if uri in self .import_map :
296309 try :
297310 with open (self .import_map [uri ], "r" , encoding = "utf-8" ) as f :
298311 return json .load (f )
299312 except Exception as e :
300313 self ._err (f"Failed to load imported schema from { self .import_map [uri ]} : { e } " , "#/import" )
301314 return None
302- # Simulated external schemas for testing purposes.
303- EXTERNAL_SCHEMAS = {
304- "https://example.com/people.json" : {
305- "$schema" : "https://json-structure.org/meta/core/v0/#" ,
306- "$id" : "https://example.com/people.json" ,
307- "name" : "Person" ,
308- "type" : "object" ,
309- "properties" : {
310- "firstName" : {"type" : "string" },
311- "lastName" : {"type" : "string" },
312- "address" : {"$ref" : "#/definitions/Address" }
313- },
314- "definitions" : {
315- "Address" : {
316- "name" : "Address" ,
317- "type" : "object" ,
318- "properties" : {
319- "street" : {"type" : "string" },
320- "city" : {"type" : "string" }
321- }
322- }
323- }
324- },
325- "https://example.com/address.json" : {
326- "$schema" : "https://json-structure.org/meta/core/v0/#" ,
327- "$id" : "https://example.com/address.json" ,
328- "name" : "Address" ,
329- "type" : "object" ,
330- "properties" : {
331- "street" : {"type" : "string" },
332- "city" : {"type" : "string" }
333- }
334- }
335- }
336- return EXTERNAL_SCHEMAS .get (uri )
315+ # URI not found in external_schemas or import_map
316+ return None
337317
338318 def _validate_namespace (self , obj , path ):
339319 """
0 commit comments