34
35:- module(sparql_csv_result,
36 [ sparql_write_csv_result/3 37 ]). 38:- use_module(library(csv)). 39:- use_module(library(assoc)). 40:- use_module(library(option)). 41:- use_module(library(sgml_write)). 42:- use_module(library(semweb/rdf_db)). 43:- if(exists_source(library(semweb/rdf11))). 44:- use_module(library(semweb/rdf11),
45 [ rdf_lexical_form/2
46 ]). 47:- endif. 48
53
54sparql_csv_mime_type('text/tab-separated-values; charset=UTF-8').
55
69
70sparql_write_csv_result(Out, select(VarTerm, Rows), Options) :-
71 !,
72 option(bnode_state(BNodes0-BNodes), Options, _),
73 ( var(BNodes0)
74 -> empty_assoc(BNodeDict),
75 BNodes0 = bnode(1, BNodeDict)
76 ; true
77 ),
78 rows_to_csv(Rows, CSVRows, BNodes0, BNodes),
79 ( option(http_header(true), Options, true)
80 -> sparql_csv_mime_type(ContentType),
81 format('Content-type: ~w~n~n', [ContentType])
82 ; true
83 ),
84 ( option(header_row(true), Options, true)
85 -> csv_write_stream(Out, [VarTerm|CSVRows], [])
86 ; csv_write_stream(Out, CSVRows, [])
87 ).
88sparql_write_csv_result(_Out, Result, _Options) :-
89 !,
90 domain_error(csv_sparql_result, Result).
91
92rows_to_csv([], [], BNodeDict, BNodeDict).
93rows_to_csv([H0|T0], [H|T], BNodeDict0, BNodeDict) :-
94 row_to_csv(H0, H, BNodeDict0, BNodeDict1),
95 rows_to_csv(T0, T, BNodeDict1, BNodeDict).
96
97row_to_csv(RDF, CSV, BNodeDict0, BNodeDict) :-
98 RDF =.. [_|RDFFields],
99 fields_to_csv(RDFFields, CSVFields, BNodeDict0, BNodeDict),
100 CSV =.. [row|CSVFields].
101
102fields_to_csv([], [], BNodeDict, BNodeDict).
103fields_to_csv([H0|T0], [H|T], BNodeDict0, BNodeDict) :-
104 field_to_csv(H0, H, BNodeDict0, BNodeDict1),
105 fields_to_csv(T0, T, BNodeDict1, BNodeDict).
106
107field_to_csv(Var, '', BNodeDict, BNodeDict) :-
108 ( var(Var)
109 -> true
110 ; Var == '$null$'
111 ),
112 !.
113field_to_csv(literal(Literal), Text, BNodeDict, BNodeDict) :-
114 literal_text(Literal, Text),
115 !.
116field_to_csv(@(LangString,Lang), Text, BNodeDict, BNodeDict) :-
117 literal_text(@(LangString,Lang), Text),
118 !.
119field_to_csv(^^(Lexical,Type), Text, BNodeDict, BNodeDict) :-
120 literal_text(^^(Lexical,Type), Text),
121 !.
122field_to_csv(Resource, BNode, BNodeDict0, BNodeDict) :-
123 rdf_is_bnode(Resource),
124 !,
125 BNodeDict0 = bnode(N0, Dict0),
126 ( get_assoc(Resource, Dict0, BNode)
127 -> BNodeDict = BNodeDict0
128 ; succ(N0, N),
129 atomic_list_concat(['_:node', N], BNode),
130 put_assoc(Resource, Dict0, BNode, Dict),
131 BNodeDict = bnode(N, Dict)
132 ).
133field_to_csv(Atomic, Atomic, BNodeDict, BNodeDict) :-
134 atomic(Atomic),
135 !.
136field_to_csv(Term, String, BNodeDict, BNodeDict) :-
137 term_string(Term, String).
138
140
141literal_text(type(Type, Value), Text) :-
142 !,
143 atom(Type),
144 ( rdf_equal(Type, rdf:'XMLLiteral')
145 -> with_output_to(string(Text),
146 xml_write(Value, [header(false)]))
147 ; atomic(Value)
148 -> Text = Value
149 ; term_string(Value, Text)
150 ).
151literal_text(lang(Lang, LangText), Text) :-
152 !,
153 atom(Lang),
154 literal_text(LangText, Text).
155literal_text(@(LangText, Lang), Text) :-
156 !,
157 atom(Lang),
158 literal_text(LangText, Text).
159:- if(current_predicate(rdf_lexical_form/2)). 160literal_text(^^(Lexical, Type), Text) :-
161 !,
162 rdf_lexical_form(^^(Lexical,Type), ^^(Text,_)).
163:- endif. 164literal_text(Text, Text) :-
165 atom(Text),
166 !.
167literal_text(Text, Text) :-
168 string(Text),
169 !.
170
171
172 175
176:- multifile
177 rdf_io:write_table/4. 178
179rdf_io:write_table(csv, _, Rows, Options) :-
180 memberchk(variables(Vars), Options),
181 !,
182 ( is_list(Vars)
183 -> VarTerm =.. [vars|Vars]
184 ; VarTerm = Vars
185 ),
186 sparql_write_csv_result(current_output, select(VarTerm, Rows),
187 [ content_type(text/plain),
188 Options
189 ])