Skip to content

Commit

Permalink
The updated logic includes handling various data formats like dates, …
Browse files Browse the repository at this point in the history
…booleans, numbers, coordinates, and pre-tagged language literals.
  • Loading branch information
darnelleMelvin authored Dec 20, 2024
1 parent 54c2b6e commit d0d58c4
Showing 1 changed file with 66 additions and 17 deletions.
83 changes: 66 additions & 17 deletions csv2rdfConverter.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,83 @@
from dateutil import parser
import re


def is_coordinate(value):
# Check if the value matches the pattern for coordinates
"""
Check if the value matches the pattern for WKT-style coordinates.
"""
return re.match(r"^Point\(-?\d+(\.\d+)? -?\d+(\.\d+)?\)$", value)

def is_numeric(value):
"""
Check if the value is numeric (integer or float).
"""
try:
float(value)
return True
except ValueError:
return False

def is_boolean(value):
return value.lower() in {"true", "false"}

def is_integer(value):
try:
int(value)
return True
except ValueError:
return False

def is_decimal(value):
try:
float(value)
return '.' in value and not value.isdigit()
except ValueError:
return False

def format_triple(subject, predicate, obj):
# Check if object is a URI
"""
Format the RDF triple based on the type of the object.
"""
# URIs
if obj.startswith("http"):
return f"<{subject}> <{predicate}> <{obj}> ."
else:
# Check if object is a datetime
try:
parsed_date = parser.isoparse(obj)
# Format as xsd:dateTime

# Datetimes
try:
parsed_date = parser.isoparse(obj)
if "T" in obj:
return f"<{subject}> <{predicate}> \"{parsed_date.isoformat()}\"^^<http://www.w3.org/2001/XMLSchema#dateTime> ."
except ValueError:
# Check if object is a coordinate
if is_coordinate(obj):
return f"<{subject}> <{predicate}> \"{obj}\"^^<http://www.opengis.net/ont/geosparql#wktLiteral> ."
# Escape single and double quotes within the object string
obj = obj.replace('"', '\\"')
# Specify English language tag
return f"<{subject}> <{predicate}> \"{obj}\"@en ."
else:
return f"<{subject}> <{predicate}> \"{parsed_date.date()}\"^^<http://www.w3.org/2001/XMLSchema#date> ."
except ValueError:
pass

# Booleans
if is_boolean(obj):
return f"<{subject}> <{predicate}> \"{obj.lower()}\"^^<http://www.w3.org/2001/XMLSchema#boolean> ."

# Numbers
if is_integer(obj):
return f"<{subject}> <{predicate}> \"{obj}\"^^<http://www.w3.org/2001/XMLSchema#integer> ."
if is_decimal(obj):
return f"<{subject}> <{predicate}> \"{obj}\"^^<http://www.w3.org/2001/XMLSchema#decimal> ."

# Coordinates
if is_coordinate(obj):
return f"<{subject}> <{predicate}> \"{obj}\"^^<http://www.opengis.net/ont/geosparql#wktLiteral> ."

# Check for existing language tags
if re.match(r'^".*"@[a-z]{2}$', obj):
return f"<{subject}> <{predicate}> {obj} ."

# Escape and default to string with @en
obj = obj.replace('"', '\\"')
return f"<{subject}> <{predicate}> \"{obj}\"@en ."

def convert_csv_to_nt(input_csv, output_nt):
"""
Convert a CSV file to an N-Triples (.nt) file.
"""
with open(input_csv, 'r', newline='', encoding='utf-8') as csvfile, open(output_nt, 'w', encoding='utf-8') as ntfile:
csvreader = csv.reader(csvfile)
next(csvreader) # Skip the header row
Expand All @@ -43,7 +93,6 @@ def convert_csv_to_nt(input_csv, output_nt):
else:
print(f"Error: Invalid row format - should contain at least 3 columns. Row: {row}")


if __name__ == "__main__":
input_csv_file = "inputFilepathHere.csv" # Change this to the path of your input CSV file
output_nt_file = "outputFilepathHere.nt" # Change this to the desired path of your output .nt file
Expand Down

0 comments on commit d0d58c4

Please sign in to comment.