|
5 | 5 | from io import StringIO
|
6 | 6 | from os.path import dirname, abspath
|
7 | 7 | from rdflib import Graph, Literal, URIRef
|
| 8 | +from rdflib.graph import Seq |
8 | 9 | from rdflib.namespace import XSD, RDF
|
9 | 10 |
|
10 | 11 | import odml
|
@@ -123,11 +124,27 @@ def save_element(self, e, node=None):
|
123 | 124 | elif isinstance(fmt, Property.__class__) and \
|
124 | 125 | k == 'value' and len(getattr(e, k)) > 0:
|
125 | 126 | values = getattr(e, k)
|
126 |
| - bag = URIRef(odmlns + str(uuid.uuid4())) |
127 |
| - self.g.add((bag, RDF.type, RDF.Bag)) |
128 |
| - self.g.add((curr_node, fmt.rdf_map(k), bag)) |
| 127 | + seq = URIRef(odmlns + str(uuid.uuid4())) |
| 128 | + self.g.add((seq, RDF.type, RDF.Seq)) |
| 129 | + self.g.add((curr_node, fmt.rdf_map(k), seq)) |
| 130 | + # rdflib so far does not respect RDF:li item order |
| 131 | + # in RDF:Seq on loading so we have to use custom |
| 132 | + # numbered Node elements for now. Once rdflib upgrades |
| 133 | + # this should be reversed to RDF:li again! |
| 134 | + # see https://github.com/RDFLib/rdflib/issues/280 |
| 135 | + # -- keep until supported |
| 136 | + # bag = URIRef(odmlns + str(uuid.uuid4())) |
| 137 | + # self.g.add((bag, RDF.type, RDF.Bag)) |
| 138 | + # self.g.add((curr_node, fmt.rdf_map(k), bag)) |
| 139 | + # for v in values: |
| 140 | + # self.g.add((bag, RDF.li, Literal(v))) |
| 141 | + |
| 142 | + counter = 1 |
129 | 143 | for v in values:
|
130 |
| - self.g.add((bag, RDF.li, Literal(v))) |
| 144 | + pred = "%s_%s" % (str(RDF), counter) |
| 145 | + self.g.add((seq, URIRef(pred), Literal(v))) |
| 146 | + counter = counter + 1 |
| 147 | + |
131 | 148 | # adding entities' properties
|
132 | 149 | else:
|
133 | 150 | val = getattr(e, k)
|
@@ -258,9 +275,20 @@ def parse_property(self, prop_uri):
|
258 | 275 | elems = list(self.g.objects(subject=prop_uri, predicate=attr[1]))
|
259 | 276 | if attr[0] == "value" and len(elems) > 0:
|
260 | 277 | prop_attrs[attr[0]] = []
|
| 278 | + |
| 279 | + # rdflib does not respect order with RDF.li items yet, see comment above |
| 280 | + # support both RDF.li and rdf:_nnn for now. |
| 281 | + # Remove rdf:_nnn once rdflib respects RDF.li order in an RDF.Seq obj. |
261 | 282 | values = list(self.g.objects(subject=elems[0], predicate=RDF.li))
|
262 |
| - for v in values: |
263 |
| - prop_attrs[attr[0]].append(v.toPython()) |
| 283 | + if len(values) > 0: |
| 284 | + for v in values: |
| 285 | + prop_attrs[attr[0]].append(v.toPython()) |
| 286 | + else: |
| 287 | + # rdf:__nnn part |
| 288 | + valseq = Seq(graph=self.g, subject=elems[0]) |
| 289 | + for seqitem in valseq: |
| 290 | + prop_attrs[attr[0]].append(seqitem.toPython()) |
| 291 | + |
264 | 292 | elif attr[0] == "id":
|
265 | 293 | prop_attrs[attr[0]] = prop_uri.split("#", 1)[1]
|
266 | 294 | else:
|
|
0 commit comments