def map_object_literal( v: Union[str, jsonasobj.JsonObj]) -> ShExJ.ObjectLiteral: """ `PyShEx.jsg <https://github.com/hsolbrig/ShExJSG/ShExJSG/ShExJ.jsg>`_ does not add identifying types to ObjectLiterals. This routine re-identifies the types """ # TODO: isinstance(v, JSGString) should work here, but it doesn't with IRIREF(http://a.example/v1) return v if issubclass(type(v), JSGString) or (isinstance(v, JSGObject) and 'type' in v) else \ ShExJ.IRIREF(v) if isinstance(v, str) else ShExJ.ObjectLiteral(**v._as_dict)
def shapeRef_to_iriref(self, ref: ShExDocParser.ShapeRefContext) -> ShExJ.IRIREF: """ shapeRef: ATPNAME_NS | ATPNAME_LN | '@' shapeExprLabel """ if ref.ATPNAME_NS(): return ShExJ.IRIREF( self._lookup_prefix(ref.ATPNAME_NS().getText()[1:])) elif ref.ATPNAME_LN(): prefix, local = ref.ATPNAME_LN().getText()[1:].split(':', 1) return ShExJ.IRIREF( self._lookup_prefix(prefix + ':') + (local if local else "")) else: return self.shapeexprlabel_to_IRI(ref.shapeExprLabel())
def tripleexprlabel_to_iriref(self, tripleExprLabel: ShExDocParser.TripleExprLabelContext) \ -> Union[ShExJ.BNODE, ShExJ.IRIREF]: """ tripleExprLabel: iri | blankNode """ if tripleExprLabel.iri(): return self.iri_to_iriref(tripleExprLabel.iri()) else: return ShExJ.BNODE(tripleExprLabel.blankNode().getText())
def prefixedname_to_iriref( self, prefix: ShExDocParser.PrefixedNameContext) -> ShExJ.IRIREF: """ prefixedName: PNAME_LN | PNAME_NS PNAME_NS: PN_PREFIX? ':' ; PNAME_LN: PNAME_NS PN_LOCAL ; """ return ShExJ.IRIREF(self.prefixedname_to_str(prefix))
def shapeexprlabel_to_IRI(self, shapeExprLabel: ShExDocParser.ShapeExprLabelContext) \ -> Union[ShExJ.BNODE, ShExJ.IRIREF]: """ shapeExprLabel: iri | blankNode """ if shapeExprLabel.iri(): return self.iri_to_iriref(shapeExprLabel.iri()) else: return ShExJ.BNODE(shapeExprLabel.blankNode().getText())
def test_predicate_scan(self): c = setup_context(shex_1, rdf_1) predicates: List[URIRef] = [] c.visit_shapes( c.shapeExprFor(IRIREF('http://schema.example/UserShape')), triple_expr_finder, predicates) self.assertEqual([RDF.type], predicates) # Quick test of the utility function self.assertEqual( predicates_in_expression( c.shapeExprFor(IRIREF('http://schema.example/UserShape')), c), [ShExJ.IRIREF(str(u)) for u in predicates])
def literal_to_ObjectLiteral( self, literal: ShExDocParser.LiteralContext) -> ShExJ.ObjectLiteral: """ literal: rdfLiteral | numericLiteral | booleanLiteral """ rval = ShExJ.ObjectLiteral() if literal.rdfLiteral(): rdflit = literal.rdfLiteral() txt = rdflit.string().getText() quote_char = '' if len(txt) > 5 and (txt.startswith("'''") and txt.endswith("'''") or txt.startswith('"""') and txt.endswith('"""')): txt = txt[3:-3] else: quote_char = txt[0] txt = txt[1:-1] txt = self.fix_text_escapes(txt, quote_char) rval.value = String(txt) if rdflit.LANGTAG(): rval.language = ShExJ.LANGTAG( rdflit.LANGTAG().getText()[1:].lower()) if rdflit.datatype(): rval.type = self.iri_to_str(rdflit.datatype().iri()) elif literal.numericLiteral(): numlit = literal.numericLiteral() if numlit.INTEGER(): rval.value = String(numlit.INTEGER().getText()) rval.type = RDF_INTEGER_TYPE elif numlit.DECIMAL(): rval.value = String(numlit.DECIMAL().getText()) rval.type = RDF_DECIMAL_TYPE elif numlit.DOUBLE(): rval.value = String(numlit.DOUBLE().getText()) rval.type = RDF_DOUBLE_TYPE elif literal.booleanLiteral(): rval.value = String(literal.booleanLiteral().getText().lower()) rval.type = RDF_BOOL_TYPE return rval
def iri_to_iriref(self, iri_: ShExDocParser.IriContext) -> ShExJ.IRIREF: """ iri: IRIREF | prefixedName prefixedName: PNAME_LN | PNAME_NS """ return ShExJ.IRIREF(self.iri_to_str(iri_))
def iriref_to_shexj_iriref(self, ref: ShExDocParser.IRIREF) -> ShExJ.IRIREF: """ IRIREF: '<' (~[\u0000-\u0020=<>\"{}|^`\\] | UCHAR)* '>' IRI: (PN_CHARS | '!' | ''.' | ':' | '/' | '\\' | '#' | '@' | '%' | '&' | UCHAR)* """ return ShExJ.IRIREF(self.iriref_to_str(ref))
def __init__(self): self.schema = ShExJ.Schema() self.ld_prefixes: Dict[PREFIXstr, IRIstr] = {} # prefixes in the JSON-LD module self.prefixes: Dict[PREFIXstr, IRIstr] = {} # Assigned prefixes self.base: Optional[IRIstr] = None
import re from typing import Optional from ShExJSG import ShExJ from pyjsg.jsglib import * from rdflib import RDF, XSD from pyshexc.parser.ShExDocParser import ShExDocParser IRIstr = str PREFIXstr = str RDF_TYPE = ShExJ.IRIREF(str(RDF.type)) RDF_INTEGER_TYPE = ShExJ.IRIREF(str(XSD.integer)) RDF_DOUBLE_TYPE = ShExJ.IRIREF(str(XSD.double)) RDF_DECIMAL_TYPE = ShExJ.IRIREF(str(XSD.decimal)) RDF_BOOL_TYPE = ShExJ.IRIREF(str(XSD.boolean)) class ParserContext: """ Context maintained across ShExC parser implementation modules """ def __init__(self): self.schema = ShExJ.Schema() self.ld_prefixes: Dict[PREFIXstr, IRIstr] = {} # prefixes in the JSON-LD module self.prefixes: Dict[PREFIXstr, IRIstr] = {} # Assigned prefixes self.base: Optional[IRIstr] = None
def _resolve_relative_uri( self, ref: Union[URIRef, BNode, ShExJ.shapeExprLabel]) -> ShExJ.shapeExprLabel: return ShExJ.IRIREF(str(self.base_namespace[str( ref)])) if ':' not in str(ref) and self.base_namespace else ref
def eval_entry(self, entry_name: str) -> bool: mes = self.mfst.entries[entry_name] for me in mes: # There can be more than one entry per name... # Determine the start point if not self.started: if not me.name.startswith(START_AFTER): self.start_skipped += 1 return True else: self.started = True if VERBOSE: print( f"STARTED - Skipped {self.start_skipped} entries") # Determine whether this entry should be skipped should_skip = False # Skip skipped_traits = list(me.traits.intersection(skip_traits)) if skipped_traits: if VERBOSE: print( f"Skipping {me.name} ({', '.join([self.URIname(t) for t in me.traits])}) - Skipped trait" ) key = str(skipped_traits[0]).replace(str(SHT), 'sht:') if key not in self.skip_reasons: self.skip_reasons[key] = 0 self.skip_reasons[key] = self.skip_reasons[key] + 1 self.skip(me.name) should_skip = True elif me.name in self.expected_failures: if VERBOSE: print( f"Skipping {me.name} ({', '.join([self.URIname(t) for t in me.traits])})" f" - {self.expected_failures[me.name]}") key = self.expected_failures[me.name] if key not in self.skip_reasons: self.skip_reasons[key] = 0 self.skip_reasons[key] = self.skip_reasons[key] + 1 self.skip(me.name) should_skip = True if should_skip and not TEST_SKIPS_ONLY: return True if TEST_SKIPS_ONLY and not should_skip: return True # Validate the entry if VERBOSE: shex_uri = self.mfst.schema_loader.location_rewrite( me.schema_uri) data_uri = self.mfst.data_redirector.uri_for(me.data_uri) \ if self.mfst.data_redirector else me.data_uri print( f"Testing {me.name} ({'P' if me.should_pass else 'F'}): {shex_uri} - {data_uri}" ) g, s = me.data_graph(), me.shex_schema() if g is None and me.data_uri: print("\t ERROR: Unable to load data file") print(f"\t TRAITS: ({','.join(me.traits)})") self.skip(me.name) return True if not s: print(f"\t ERROR: Unable to load schema {me.schema_uri}") print(f"\t TRAITS: ({','.join(me.traits)})") self.nskipped += 1 self.skip(me.name) return False cntxt = Context(g, s, me.extern_shape_for, base_namespace=BASE_FILE_LOC) cntxt.debug_context.debug = DEBUG map_ = FixedShapeMap() focus = self.mfst.data_uri(me.focus) if not focus: print("\t***** FAIL *****") print(f"\tFocus: {me.focus} not in schema") print(f"\t TRAITS: ({','.join(me.traits)})") self.fail(me.name) return False # if ':' not in focus: # focus = "file://" + focus map_.add( ShapeAssociation( focus, ShExJ.IRIREF(me.shape) if me.shape else START)) ################################# # Actual validation occurs here ################################# rslt = isValid(cntxt, map_) test_result, reasons = rslt[0] or not me.should_pass, rslt[1] # Analyze the result if not VERBOSE and not test_result: print( f"Failed {me.name} ({'P' if me.should_pass else 'F'}): {me.schema_uri} - {me.data_uri}" ) print(f"\t TRAITS: ({','.join(me.traits)})") if test_result: self.pass_(me.name) else: if VERBOSE: print("\t**** FAIL *****") print(f"\t TRAITS: ({','.join(me.traits)})") for reason in reasons: print(f"\t{reason}") self.fail(me.name) return test_result
def test_extern_str(self): mfst = ShExManifest(manifest_ttl, 'turtle') me = mfst.entries['shapeExtern_pass'][0] self.assertIsNotNone( me.extern_shape_for(ShExJ.IRIREF("http://a.example/Sext")))
def __init__(self): self.schema = ShExJ.Schema() self.ld_prefixes = {} # prefixes in the JSON-LD module self.prefixes = {} # Assigned prefixes self.base = None