diff --git a/rdflib/extras/gregorian_type.py b/rdflib/extras/gregorian_type.py new file mode 100644 index 000000000..4f0031541 --- /dev/null +++ b/rdflib/extras/gregorian_type.py @@ -0,0 +1,14 @@ +class GregorianType: + def __init__(self, lexical_value : str, datatype : int): + self.lexical_value = lexical_value + lvalue = lexical_value.split('-') + self.gYear = lvalue[0] + self.gMonth = None + if datatype == 2: + self.gMonth = lvalue[1] + + def __str__(self): + if self.gMonth == None: + return self.gYear + return self.gYear + '-' + self.gMonth + diff --git a/rdflib/term.py b/rdflib/term.py index a93e9c50f..40fc26f8f 100644 --- a/rdflib/term.py +++ b/rdflib/term.py @@ -26,6 +26,7 @@ # from __future__ import unicode_literals from fractions import Fraction +from rdflib.extras.gregorian_type import GregorianType __all__ = [ "bind", @@ -76,7 +77,6 @@ _invalid_uri_chars = '<>" {}|\\^`' - def _is_valid_uri(uri): return all(map(lambda c: ord(c) > 256 or c not in _invalid_uri_chars, uri)) @@ -543,7 +543,13 @@ def __new__(cls, lexical_or_value, lang=None, datatype=None, normalize=None): datatype = URIRef(datatype) value = None - if isinstance(lexical_or_value, Literal): + if datatype == URIRef(_XSD_GYEAR) or datatype == URIRef(_XSD_GYEARMONTH): + if datatype == URIRef(_XSD_GYEAR): + value = GregorianType(lexical_or_value, 1) + else: + value = GregorianType(lexical_or_value, 2) + + elif isinstance(lexical_or_value, Literal): # create from another Literal instance lang = lang or lexical_or_value.language @@ -558,7 +564,6 @@ def __new__(cls, lexical_or_value, lang=None, datatype=None, normalize=None): # passed a string # try parsing lexical form of datatyped literal value = _castLexicalToPython(lexical_or_value, datatype) - if value is not None and normalize: _value, _datatype = _castPythonToLiteral(value, datatype) if _value is not None and _is_valid_unicode(_value): @@ -1439,6 +1444,9 @@ def _parseBoolean(value): _OWL_RATIONAL = URIRef("http://www.w3.org/2002/07/owl#rational") _XSD_HEXBINARY = URIRef(_XSD_PFX + "hexBinary") # TODO: gYearMonth, gYear, gMonthDay, gDay, gMonth +_XSD_GYEAR = URIRef(_XSD_PFX + 'gYear') +_XSD_GYEARMONTH = URIRef(_XSD_PFX + 'gYearMonth') + _NUMERIC_LITERAL_TYPES = ( _XSD_INTEGER, @@ -1565,40 +1573,38 @@ def _castPythonToLiteral(obj, datatype): XSDToPython = { None: None, # plain literals map directly to value space - URIRef(_XSD_PFX + "time"): parse_time, - URIRef(_XSD_PFX + "date"): parse_date, - URIRef(_XSD_PFX + "gYear"): parse_date, - URIRef(_XSD_PFX + "gYearMonth"): parse_date, - URIRef(_XSD_PFX + "dateTime"): parse_datetime, - URIRef(_XSD_PFX + "duration"): parse_duration, - URIRef(_XSD_PFX + "dayTimeDuration"): parse_duration, - URIRef(_XSD_PFX + "yearMonthDuration"): parse_duration, - URIRef(_XSD_PFX + "hexBinary"): _unhexlify, - URIRef(_XSD_PFX + "string"): None, - URIRef(_XSD_PFX + "normalizedString"): None, - URIRef(_XSD_PFX + "token"): None, - URIRef(_XSD_PFX + "language"): None, - URIRef(_XSD_PFX + "boolean"): _parseBoolean, - URIRef(_XSD_PFX + "decimal"): Decimal, - URIRef(_XSD_PFX + "integer"): long_type, - URIRef(_XSD_PFX + "nonPositiveInteger"): int, - URIRef(_XSD_PFX + "long"): long_type, - URIRef(_XSD_PFX + "nonNegativeInteger"): int, - URIRef(_XSD_PFX + "negativeInteger"): int, - URIRef(_XSD_PFX + "int"): long_type, - URIRef(_XSD_PFX + "unsignedLong"): long_type, - URIRef(_XSD_PFX + "positiveInteger"): int, - URIRef(_XSD_PFX + "short"): int, - URIRef(_XSD_PFX + "unsignedInt"): long_type, - URIRef(_XSD_PFX + "byte"): int, - URIRef(_XSD_PFX + "unsignedShort"): int, - URIRef(_XSD_PFX + "unsignedByte"): int, - URIRef(_XSD_PFX + "float"): float, - URIRef(_XSD_PFX + "double"): float, - URIRef(_XSD_PFX + "base64Binary"): lambda s: base64.b64decode(s), - URIRef(_XSD_PFX + "anyURI"): None, + URIRef(_XSD_PFX + 'time'): parse_time, + URIRef(_XSD_PFX + 'date'): parse_date, + URIRef(_XSD_PFX + 'dateTime'): parse_datetime, + URIRef(_XSD_PFX + 'duration'): parse_duration, + URIRef(_XSD_PFX + 'dayTimeDuration'): parse_duration, + URIRef(_XSD_PFX + 'yearMonthDuration'): parse_duration, + URIRef(_XSD_PFX + 'hexBinary'): _unhexlify, + URIRef(_XSD_PFX + 'string'): None, + URIRef(_XSD_PFX + 'normalizedString'): None, + URIRef(_XSD_PFX + 'token'): None, + URIRef(_XSD_PFX + 'language'): None, + URIRef(_XSD_PFX + 'boolean'): lambda i: i.lower() == 'true' or (i.isdigit() and int(i) == True), + URIRef(_XSD_PFX + 'decimal'): Decimal, + URIRef(_XSD_PFX + 'integer'): long_type, + URIRef(_XSD_PFX + 'nonPositiveInteger'): int, + URIRef(_XSD_PFX + 'long'): long_type, + URIRef(_XSD_PFX + 'nonNegativeInteger'): int, + URIRef(_XSD_PFX + 'negativeInteger'): int, + URIRef(_XSD_PFX + 'int'): long_type, + URIRef(_XSD_PFX + 'unsignedLong'): long_type, + URIRef(_XSD_PFX + 'positiveInteger'): int, + URIRef(_XSD_PFX + 'short'): int, + URIRef(_XSD_PFX + 'unsignedInt'): long_type, + URIRef(_XSD_PFX + 'byte'): int, + URIRef(_XSD_PFX + 'unsignedShort'): int, + URIRef(_XSD_PFX + 'unsignedByte'): int, + URIRef(_XSD_PFX + 'float'): float, + URIRef(_XSD_PFX + 'double'): float, + URIRef(_XSD_PFX + 'base64Binary'): lambda s: base64.b64decode(s), + URIRef(_XSD_PFX + 'anyURI'): None, _RDF_XMLLITERAL: _parseXML, - _RDF_HTMLLITERAL: _parseHTML, + _RDF_HTMLLITERAL: _parseHTML } _toPythonMapping = {} @@ -1804,5 +1810,4 @@ def recurse(): if __name__ == "__main__": import doctest - doctest.testmod()