Repository navigation
Conversation
jdsika
marked this pull request as draft
October 5, 2026 10:27
jdsika
force-pushed
the
fix/string-derived-anyuri-types-stay-literals
branch
from
October 5, 2026 10:42
75f9be6 to
3e1b4ef
Compare
jdsika
marked this pull request as ready for review
October 5, 2026 10:55
A string-derived type with uri: xsd:anyURI holds URI-reference data, including relative paths. Preserve its typed literal in JSON-LD contexts, SHACL, ShEx and runtime RDF serialization, matching OWL datatype mode. Resolve type ancestry and the effective expanded datatype together so inherited types, prefix aliases and explicit datatype overrides agree. Legacy generators inspect a copy of their resolved schema instead of reopening source files. Preserve the existing JSON-LD/OWL IRI option and keep the runtime independent of a new compiler/runtime shared API. Exercise actual JSON-LD expansion, Python-to-RDF serialization, SHACL and ShEx validation, including negative RDF-term substitutions. Test mixed class/literal JSON-LD and SHACL ranges; general ShEx any_of remains a documented pre-existing limitation outside this correction. Signed-off-by: jdsika <carlo.van-driesten@vdl.digital>
jdsika
force-pushed
the
fix/string-derived-anyuri-types-stay-literals
branch
from
October 14, 2026 06:15
3e1b4ef to
d9d2745
Compare
This was referenced Oct 14, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem and behavior
A custom type derived from
stringwithuri: xsd:anyURIrepresents a URI reference held as literal data. Generating@idfor a relative value such as./data/file.pngresolves it against the JSON-LD document base and changes that value into a different RDF term.This change preserves such values as
xsd:anyURIliterals across JSON-LD contexts, SHACL, ShEx and the RDF dumper, matching OWL's datatype-property representation. LinkML'suri/uriorcuriefamily retains its existing IRI behavior in SHACL, ShEx and the dumper, and its existing opt-in IRI representation in JSON-LD/OWL.Implementation and generality
xs:anyURIhave the same behavior asxsd:anyURI.xsd:stringremains literal-valued even with URI ancestry.source_filenor change the provenance of the schema used for output.xsd:anyURItype constraints for string-derived types. Its existing enum and slot-expression behavior is unchanged.No consumer class, property, filename, vocabulary list or URI pattern is special-cased. Identifier slots retain their distinct RDF-subject semantics.
Standards, modelling and options
XSD anyURI permits relative URI references as literal values. RDF literals and IRI nodes are distinct terms. JSON-LD type coercion with
@idcreates identifiers and resolves relative references; datatype coercion preserves the literal representation.The existing
--xsd-anyuri-as-irioption was introduced in upstream #3292. This PR introduces no flag and preserves its default. The explicit custom type already distinguishes literal-valued data, so retaining that data needs no further option. Broader defaults for the built-in URI types remain a separate, existing design discussion in #2495; the default generators are not claimed to agree on those types when the existing option is disabled.The downstream example in OMB #106 is a
UriReferencetype for file-location data. The regression schemas are generic and exercise both relative and absolute values, not OMB-specific vocabulary.Cross-generator tests
For scalar ranges, real JSON-LD expansion and generated Python-to-RDF serialization produce isomorphic graphs. pySHACL (including meta-SHACL) and ShEx evaluation accept the resulting graphs and reject IRI/plain-literal substitutions for typed-literal values. Tests also check OWL property kinds in datatype mode, aliases, inherited types, explicit overrides, and source-file independence. Class/literal unions are tested through JSON-LD and SHACL. The runtime tests serialize and parse their RDF terms independently of the compiler package. No mocks are used.
Remaining cross-generator limitation: ShEx does not implement slot-level
any_of; a class-or-literal union therefore does not have equivalent ShEx validation. This pre-existing gap requires separate work on branch constraints, collection semantics and class node kinds. An exploratory union implementation failed 33 full-suite cases, and negative consumer tests exposed literal acceptance by empty class shapes. None of that broader implementation is included or claimed as fixed here. Existing assertions were not weakened to make this URI correction pass.This establishes the tested RDF representation contract for scalar ranges. It does not change JSON Schema/Python validation semantics for scalar values.
Measured effect
SHACL verdict for a valid value of each range, with data loaded through the generated JSON-LD context, the context with
--xsd-anyuri-as-iri, and the runtime RDF dumper:typeof: string,uri: xsd:anyURI^^xsd:anyURIliterals)typeof: uriuri,uriorcurieNo cell gets worse. The remaining ✗ for the built-in types under the default context is the existing default discussed in linkml#2495.
nodeidentifiervalues are written as^^shex:nonLiteralliterals on every data path and never satisfy SHACL'ssh:BlankNodeOrIRI; that is a separate, pre-existing bug (fork issue #51).Validation
bd102062b. Full compiler suite: 12,420 passed; runtime suite: 1,836 passed.