Skip to content

Commit 178d1d2

Browse files
committed
Compact XSD strings
Signed-off-by: Alex Nelson <[email protected]>
1 parent 10a5e57 commit 178d1d2

File tree

2 files changed

+66
-1
lines changed

2 files changed

+66
-1
lines changed

case_example_mapping/__init__.py

+4
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
11
__version__ = "0.0.1"
2+
3+
from typing import Union
4+
5+
JSON = Union[None, bool, dict[str, "JSON"], float, int, list["JSON"], str]

case_example_mapping/rdf_to_case.py

+62-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,69 @@
1+
import json
12
import sys
3+
from io import TextIOWrapper
24

35
from rdflib import Graph, Literal, Namespace, URIRef
46
from rdflib.namespace import RDF, XSD
57

8+
from case_example_mapping import JSON
9+
10+
STR_XSD_STRING = str(XSD.string)
11+
12+
13+
def compact_xsd_strings(json_object: JSON) -> JSON:
14+
"""
15+
Some JSON-LD serializers export all literals with datatype
16+
annotations. A string-literal without a datatype can be optionally
17+
exported with a datatype annotation of ``xsd:string``, or left to be
18+
interpreted as a ``xsd:string`` by default. This function compacts
19+
string-literals that are ``xsd:string``-typed into a JSON String
20+
instead of a JSON Object.
21+
22+
>>> from rdflib import XSD
23+
>>> x = {
24+
... "@id": "http://example.org/s",
25+
... "http://example.org/p": [
26+
... {
27+
... "@type": str(XSD.string),
28+
... "@value": "o"
29+
... }
30+
... ]
31+
... }
32+
>>> x
33+
{'@id': 'http://example.org/s', 'http://example.org/p': [{'@type': 'http://www.w3.org/2001/XMLSchema#string', '@value': 'o'}]}
34+
>>> compact_xsd_strings(x)
35+
{'@id': 'http://example.org/s', 'http://example.org/p': ['o']}
36+
"""
37+
if json_object is None:
38+
return json_object
39+
elif isinstance(json_object, (bool, float, int, str)):
40+
return json_object
41+
elif isinstance(json_object, dict):
42+
if "@value" in json_object:
43+
# Reviewing Literal.
44+
if json_object.get("@type") == STR_XSD_STRING:
45+
assert isinstance(json_object["@value"], str)
46+
return json_object["@value"]
47+
else:
48+
return json_object
49+
else:
50+
return {k: compact_xsd_strings(json_object[k]) for k in json_object.keys()}
51+
elif isinstance(json_object, list):
52+
return [compact_xsd_strings(x) for x in json_object]
53+
else:
54+
raise TypeError("Unexpected type of object: %s." % type(json_object))
55+
56+
57+
def serialize_jsonld(graph: Graph, fh: TextIOWrapper) -> None:
58+
"""
59+
This function serializes the graph with a step taken to compact
60+
``xsd:string`` Literals that became JSON Objects.
61+
"""
62+
json_string = graph.serialize(format="json-ld")
63+
json_object = json.loads(json_string)
64+
json_object = compact_xsd_strings(json_object)
65+
json.dump(json_object, fh, indent=4)
66+
667

768
def main() -> None:
869
# Process the command line arguments to get the output path
@@ -52,7 +113,7 @@ def main() -> None:
52113
# Write the CASE graph to a file
53114
try:
54115
with open(output_path, "w") as case_file:
55-
case_file.write(g.serialize(format="json-ld", indent=4))
116+
serialize_jsonld(g, case_file)
56117
print(f"CASE graph exported to: {output_path}")
57118
except IOError:
58119
print(f"Error writing to path: {output_path}")

0 commit comments

Comments
 (0)