rdf-construct 0.4.1__py3-none-any.whl → 0.4.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- rdf_construct/__init__.py +1 -1
- rdf_construct/core/__init__.py +3 -2
- rdf_construct/core/serialiser.py +68 -10
- {rdf_construct-0.4.1.dist-info → rdf_construct-0.4.2.dist-info}/METADATA +1 -1
- {rdf_construct-0.4.1.dist-info → rdf_construct-0.4.2.dist-info}/RECORD +8 -8
- {rdf_construct-0.4.1.dist-info → rdf_construct-0.4.2.dist-info}/WHEEL +0 -0
- {rdf_construct-0.4.1.dist-info → rdf_construct-0.4.2.dist-info}/entry_points.txt +0 -0
- {rdf_construct-0.4.1.dist-info → rdf_construct-0.4.2.dist-info}/licenses/LICENSE +0 -0
rdf_construct/__init__.py
CHANGED
rdf_construct/core/__init__.py
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
from .ordering import sort_subjects, topo_sort_subset, sort_with_roots
|
|
4
4
|
from .profile import OrderingConfig, OrderingProfile, load_yaml
|
|
5
5
|
from .selector import select_subjects
|
|
6
|
-
from .serialiser import serialise_turtle, build_section_graph
|
|
6
|
+
from .serialiser import collect_used_namespaces, serialise_turtle, build_section_graph
|
|
7
7
|
from .utils import (
|
|
8
8
|
expand_curie,
|
|
9
9
|
extract_prefix_map,
|
|
@@ -23,6 +23,7 @@ __all__ = [
|
|
|
23
23
|
# Selector
|
|
24
24
|
"select_subjects",
|
|
25
25
|
# Serialiser
|
|
26
|
+
"collect_used_namespaces",
|
|
26
27
|
"serialise_turtle",
|
|
27
28
|
"build_section_graph",
|
|
28
29
|
# Utils
|
|
@@ -30,4 +31,4 @@ __all__ = [
|
|
|
30
31
|
"extract_prefix_map",
|
|
31
32
|
"qname_sort_key",
|
|
32
33
|
"rebind_prefixes",
|
|
33
|
-
]
|
|
34
|
+
]
|
rdf_construct/core/serialiser.py
CHANGED
|
@@ -26,6 +26,54 @@ except ImportError:
|
|
|
26
26
|
)
|
|
27
27
|
|
|
28
28
|
|
|
29
|
+
def collect_used_namespaces(
|
|
30
|
+
graph: Graph,
|
|
31
|
+
namespace_source: Graph | None = None,
|
|
32
|
+
) -> set[str]:
|
|
33
|
+
"""Collect namespace URIs that are actually used in the graph's triples.
|
|
34
|
+
|
|
35
|
+
Scans all subjects, predicates, and objects (including Literal datatype
|
|
36
|
+
URIs) to find which registered namespace URIs are referenced. Uses
|
|
37
|
+
longest-match-first ordering to correctly handle overlapping namespaces
|
|
38
|
+
(e.g. ``dc:`` vs ``dcterms:``).
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
graph: RDF graph whose triples to scan.
|
|
42
|
+
namespace_source: Optional graph whose namespace registry to match
|
|
43
|
+
against. Defaults to *graph* itself. Use this when the graph
|
|
44
|
+
being scanned has a stripped namespace manager (e.g. built
|
|
45
|
+
with ``bind_namespaces="none"``).
|
|
46
|
+
|
|
47
|
+
Returns:
|
|
48
|
+
Set of namespace URI strings that appear in the graph's triples.
|
|
49
|
+
"""
|
|
50
|
+
ns_graph = namespace_source if namespace_source is not None else graph
|
|
51
|
+
|
|
52
|
+
used_ns: set[str] = set()
|
|
53
|
+
# Sort namespaces longest-first so we match the most specific prefix
|
|
54
|
+
ns_uris = sorted(
|
|
55
|
+
[str(uri) for _, uri in ns_graph.namespace_manager.namespaces()],
|
|
56
|
+
key=len,
|
|
57
|
+
reverse=True,
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
def _match_uri(uri_str: str) -> None:
|
|
61
|
+
"""Add the best-matching namespace for *uri_str* to used_ns."""
|
|
62
|
+
for ns_uri in ns_uris:
|
|
63
|
+
if uri_str.startswith(ns_uri):
|
|
64
|
+
used_ns.add(ns_uri)
|
|
65
|
+
return
|
|
66
|
+
|
|
67
|
+
for s, p, o in graph:
|
|
68
|
+
for term in (s, p, o):
|
|
69
|
+
if isinstance(term, URIRef):
|
|
70
|
+
_match_uri(str(term))
|
|
71
|
+
elif isinstance(term, Literal) and term.datatype is not None:
|
|
72
|
+
_match_uri(str(term.datatype))
|
|
73
|
+
|
|
74
|
+
return used_ns
|
|
75
|
+
|
|
76
|
+
|
|
29
77
|
def format_term(graph: Graph, term, use_prefixes: bool = True) -> str:
|
|
30
78
|
"""Format an RDF term as a Turtle string.
|
|
31
79
|
|
|
@@ -79,8 +127,11 @@ def serialise_turtle(
|
|
|
79
127
|
This custom serialiser respects the exact order of subjects provided,
|
|
80
128
|
unlike rdflib's built-in serialisers which always sort alphabetically.
|
|
81
129
|
|
|
130
|
+
Only prefix declarations for namespaces actually used in the graph's
|
|
131
|
+
triples are emitted, filtering out rdflib's built-in defaults.
|
|
132
|
+
|
|
82
133
|
Formatting features:
|
|
83
|
-
- Prefixes sorted alphabetically at top
|
|
134
|
+
- Prefixes sorted alphabetically at top (used namespaces only)
|
|
84
135
|
- Subjects in specified order
|
|
85
136
|
- rdf:type predicate listed first for each subject
|
|
86
137
|
- Predicates ordered according to predicate_order config (or alphabetically)
|
|
@@ -95,10 +146,11 @@ def serialise_turtle(
|
|
|
95
146
|
"""
|
|
96
147
|
lines = []
|
|
97
148
|
|
|
98
|
-
# Write prefixes
|
|
149
|
+
# Write prefixes — only those actually used in the graph
|
|
150
|
+
used_ns = collect_used_namespaces(graph)
|
|
99
151
|
prefixes = sorted(graph.namespace_manager.namespaces(), key=lambda x: x[0])
|
|
100
152
|
for prefix, namespace in prefixes:
|
|
101
|
-
if prefix
|
|
153
|
+
if prefix and str(namespace) in used_ns:
|
|
102
154
|
lines.append(f"PREFIX {prefix}: <{namespace}>")
|
|
103
155
|
lines.append("") # Blank line after prefixes
|
|
104
156
|
|
|
@@ -208,8 +260,9 @@ def build_section_graph(base: Graph, subjects_ordered: list) -> Graph:
|
|
|
208
260
|
"""Build a new graph containing only the specified subjects and their triples.
|
|
209
261
|
|
|
210
262
|
Creates a filtered view of the base graph that includes all triples
|
|
211
|
-
where the subject is in the provided list.
|
|
212
|
-
|
|
263
|
+
where the subject is in the provided list. Only namespace bindings
|
|
264
|
+
that are actually used by the included triples are carried over;
|
|
265
|
+
rdflib's built-in well-known namespace defaults are suppressed.
|
|
213
266
|
|
|
214
267
|
Args:
|
|
215
268
|
base: Source RDF graph to filter
|
|
@@ -218,15 +271,20 @@ def build_section_graph(base: Graph, subjects_ordered: list) -> Graph:
|
|
|
218
271
|
Returns:
|
|
219
272
|
New graph containing only triples for the specified subjects
|
|
220
273
|
"""
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
for pfx, uri in base.namespace_manager.namespaces():
|
|
225
|
-
sg.namespace_manager.bind(pfx, uri, override=True, replace=True)
|
|
274
|
+
# Suppress rdflib's automatic well-known namespace bindings so the
|
|
275
|
+
# sub-graph starts with a clean namespace manager.
|
|
276
|
+
sg = Graph(bind_namespaces="none")
|
|
226
277
|
|
|
227
278
|
# Copy triples for each subject
|
|
228
279
|
for s in subjects_ordered:
|
|
229
280
|
for p, o in base.predicate_objects(s):
|
|
230
281
|
sg.add((s, p, o))
|
|
231
282
|
|
|
283
|
+
# Match sub-graph triples against the *base* graph's namespace registry
|
|
284
|
+
# (the sub-graph's own registry is intentionally empty at this point).
|
|
285
|
+
used_ns = collect_used_namespaces(sg, namespace_source=base)
|
|
286
|
+
for pfx, uri in base.namespace_manager.namespaces():
|
|
287
|
+
if str(uri) in used_ns:
|
|
288
|
+
sg.namespace_manager.bind(pfx, uri, override=True, replace=True)
|
|
289
|
+
|
|
232
290
|
return sg
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
rdf_construct/__init__.py,sha256=
|
|
1
|
+
rdf_construct/__init__.py,sha256=FDsnLwjSAR3yMLtq_GWucI1zAnO9hU9Bj7syUeg038c,296
|
|
2
2
|
rdf_construct/__main__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
3
|
rdf_construct/cli.py,sha256=gVkr_mx5eJ54mDIuIV6mgMjVN-k6TH-N8dYWwhIiPvU,108357
|
|
4
|
-
rdf_construct/core/__init__.py,sha256=
|
|
4
|
+
rdf_construct/core/__init__.py,sha256=qFf1u6WKHVaswipXkR9tXBGrCkNo06aGT-6c9mCOpvs,838
|
|
5
5
|
rdf_construct/core/config.py,sha256=uOAvvZ7keI8o4o6r6ESzHC4AkKHN1Ja2FADiHZqZDaM,3523
|
|
6
6
|
rdf_construct/core/ordering.py,sha256=fGw5aGIY8SpsGgbm1Z1YH5mzlDv7mU7b9Is07ekJxZg,7248
|
|
7
7
|
rdf_construct/core/predicate_order.py,sha256=ITQYC_pWtH6d4JbvOwKjyU7xGL_bSDoHHLQOTac8kMc,6688
|
|
8
8
|
rdf_construct/core/profile.py,sha256=CpA6fNMZKzDQgYa91KMylbfMv9RBiVo3AlUJ91_buzI,5475
|
|
9
9
|
rdf_construct/core/selector.py,sha256=Ie_J3ZcAHYVxk7hP2YzbtJ0oE93CikWBd8cbWq8c9PE,2386
|
|
10
|
-
rdf_construct/core/serialiser.py,sha256=
|
|
10
|
+
rdf_construct/core/serialiser.py,sha256=FRQFUx2roB5OdVm6gVyuEDdZJR773GdUKHubegk-p_I,9847
|
|
11
11
|
rdf_construct/core/utils.py,sha256=dhu92LvvNJ21UI7FpdcjW1PaoHPo6UXcgnrofhkO_WE,2557
|
|
12
12
|
rdf_construct/cq/__init__.py,sha256=PDFzRuBjlMKhyaimnOEHDpQ1Ok98xa4T6qtztju4Edw,1832
|
|
13
13
|
rdf_construct/cq/expectations.py,sha256=IHQhKd8-eetyj-jvbGn502vFcL0qoUzX_4IT0GfBSGE,11850
|
|
@@ -117,8 +117,8 @@ rdf_construct/uml/odm_renderer.py,sha256=X4QqzWXJ-FX64ZIfu0Nx6gpHbEQsJOo2hq2fbY3
|
|
|
117
117
|
rdf_construct/uml/renderer.py,sha256=Zj3udsghxXqJ5NPqvVSoIK177Vtzh-fFgsDzYxF5OoY,23755
|
|
118
118
|
rdf_construct/uml/uml_layout.py,sha256=PBd_qOBJzDq2N8SCqDJqgAoFmYnzZC4jrLgCQ4biYBM,13217
|
|
119
119
|
rdf_construct/uml/uml_style.py,sha256=ngVqmbS18Y4mAi9ggtL26IeVF5VbcOIOvalvI62jSO4,21876
|
|
120
|
-
rdf_construct-0.4.
|
|
121
|
-
rdf_construct-0.4.
|
|
122
|
-
rdf_construct-0.4.
|
|
123
|
-
rdf_construct-0.4.
|
|
124
|
-
rdf_construct-0.4.
|
|
120
|
+
rdf_construct-0.4.2.dist-info/METADATA,sha256=difpznuOH0b0YNRP77a61esgIaD2_J4q4kW8eaosHbI,15739
|
|
121
|
+
rdf_construct-0.4.2.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
|
122
|
+
rdf_construct-0.4.2.dist-info/entry_points.txt,sha256=L4Mh7BDMt2BUHq_x9BwyPVZmZ-j_wifbD574Zm3qXZY,55
|
|
123
|
+
rdf_construct-0.4.2.dist-info/licenses/LICENSE,sha256=Fh-f4K2IlA0QH5XThePUIoG6_J_UqDkQyihGfvHcvpk,1061
|
|
124
|
+
rdf_construct-0.4.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|