|
| 1 | +import json |
1 | 2 | import sys
|
| 3 | +from io import TextIOWrapper |
2 | 4 |
|
3 | 5 | from rdflib import Graph, Literal, Namespace, URIRef
|
4 | 6 | from rdflib.namespace import RDF, XSD
|
5 | 7 |
|
| 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 | + |
6 | 67 |
|
7 | 68 | def main() -> None:
|
8 | 69 | # Process the command line arguments to get the output path
|
@@ -52,7 +113,7 @@ def main() -> None:
|
52 | 113 | # Write the CASE graph to a file
|
53 | 114 | try:
|
54 | 115 | 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) |
56 | 117 | print(f"CASE graph exported to: {output_path}")
|
57 | 118 | except IOError:
|
58 | 119 | print(f"Error writing to path: {output_path}")
|
|
0 commit comments