1
+ from collections import defaultdict
2
+ from dataclasses import asdict
3
+ from typing import List
4
+
1
5
from drepr .models .parse_v2 .path_parser import PathParserV2
2
6
from drepr .utils .validator import *
7
+ from ..align import AlignmentType , RangeAlignment
3
8
4
9
from ..parse_v1 .align_parser import AlignParser
5
10
from ..parse_v1 .attr_parser import AttrParser
6
11
from ..parse_v1 .preprocessing_parser import PreprocessingParser
7
12
from ..parse_v1 .resource_parser import ResourceParser
8
13
9
14
from .sm_parser import SMParser
10
- from ..sm import SemanticModel
15
+ from ..sm import SemanticModel , ClassNode , DataNode , LiteralNode
11
16
12
17
13
18
class ReprV2Parser :
@@ -57,3 +62,83 @@ def parse(cls, raw: dict):
57
62
sm = None
58
63
59
64
return DRepr (resources , preprocessing , attrs , aligns , sm )
65
+
66
+ @classmethod
67
+ def dump (cls , drepr : 'DRepr' , simplify : bool = True , use_json_path : bool = False ):
68
+ version = '2'
69
+ sm = OrderedDict ()
70
+
71
+ class_counter = defaultdict (int )
72
+ class_ids : Dict [str , str ] = {}
73
+ for node in drepr .sm .nodes .values ():
74
+ if isinstance (node , ClassNode ):
75
+ class_counter [node .label ] += 1
76
+ class_ids [node .node_id ] = f"{ node .label } :{ class_counter [node .label ]} "
77
+ sm [class_ids [node .node_id ]] = OrderedDict ([
78
+ ("properties" , []),
79
+ ("static_properties" , []),
80
+ ("links" , [])
81
+ ])
82
+
83
+ for node in drepr .sm .nodes .values ():
84
+ if isinstance (node , DataNode ):
85
+ edge = [e for e in drepr .sm .edges .values () if e .target_id == node .node_id ][0 ]
86
+ if node .data_type is not None :
87
+ prop = (edge .label , node .attr_id , node .data_type .value )
88
+ else :
89
+ prop = (edge .label , node .attr_id )
90
+ sm [class_ids [edge .source_id ]]['properties' ].append (prop )
91
+
92
+ if isinstance (node , LiteralNode ):
93
+ edge = [e for e in drepr .sm .edges if e .target_id == node .node_id ][0 ]
94
+ if node .data_type is not None :
95
+ prop = (edge .label , node .value , node .data_type .value )
96
+ else :
97
+ prop = (edge .label , node .value )
98
+ sm [class_ids [edge .source_id ]]['static_properties' ].append (prop )
99
+
100
+ for edge in drepr .sm .edges .values ():
101
+ if isinstance (drepr .sm .nodes [edge .source_id ], ClassNode ) and isinstance (
102
+ drepr .sm .nodes [edge .target_id ], ClassNode ):
103
+ sm [class_ids [edge .source_id ]]['links' ].append ((edge .label , class_ids [edge .target_id ]))
104
+ if edge .is_subject :
105
+ sm [class_ids [edge .source_id ]]['subject' ] = drepr .sm .nodes [edge .target_id ].attr_id
106
+
107
+ sm ['prefixes' ] = drepr .sm .prefixes
108
+
109
+ preprocessing : List [dict ] = []
110
+ for prepro in drepr .preprocessing :
111
+ preprocessing .append (OrderedDict ([("type" , prepro .type .value )]))
112
+ for k , v in asdict (prepro .value ).items ():
113
+ preprocessing [- 1 ][k ] = v
114
+ preprocessing [- 1 ]["path" ] = prepro .value .path .to_lang_format (use_json_path )
115
+
116
+ return OrderedDict (
117
+ [("version" , version ),
118
+ ("resources" ,
119
+ OrderedDict (
120
+ [(res .id ,
121
+ OrderedDict ([("type" , res .type .value )] + (
122
+ [(k , v )
123
+ for k , v in asdict (res .prop ).items ()] if res .prop is not None else [])))
124
+ for res in drepr .resources ])), ("preprocessing" , preprocessing ),
125
+ ("attributes" ,
126
+ OrderedDict ([(attr .id ,
127
+ OrderedDict ([("resource_id" , attr .resource_id ),
128
+ ("path" , attr .path .to_lang_format (use_json_path )),
129
+ ("unique" , attr .unique ), ("sorted" , attr .sorted .value ),
130
+ ("value_type" , attr .value_type .value ),
131
+ ("missing_values" , attr .missing_values )]))
132
+ for attr in drepr .attrs ])),
133
+ ("alignments" , [
134
+ OrderedDict ([("type" , AlignmentType .range .value ), ("source" , align .source ),
135
+ ("target" , align .target ),
136
+ ("aligned_dims" , [
137
+ OrderedDict ([
138
+ ("source" , step .source_idx ),
139
+ ("target" , step .target_idx ),
140
+ ]) for step in align .aligned_steps
141
+ ])]) if isinstance (align , RangeAlignment ) else
142
+ OrderedDict ([("type" , AlignmentType .value .value ), ("source" , align .source ),
143
+ ("target" , align .target )]) for align in drepr .aligns
144
+ ]), ("semantic_model" , sm )])
0 commit comments