35
36:- module(sparql_xml_result,
37 [ sparql_write_xml_result/3 38 ]). 39:- use_module(library(sgml)). 40:- use_module(library(assoc)). 41:- use_module(library(option)). 42:- use_module(library('semweb/rdf_db'), [rdf_is_bnode/1, rdf_equal/2]). 43
44ns(sparql, 'http://www.w3.org/2005/sparql-results#').
45
50
51
59sparql_write_xml_result(Out, ask(TrueFalse), _Options) :-
60 !,
61 write_header(Out),
62 format(Out, ' <head/>~n', []),
63 format(Out, ' <boolean>~w</boolean>~n', [TrueFalse]),
64 format(Out, '</sparql>~n', []).
65sparql_write_xml_result(Out, update(TrueFalse), Options) :-
66 !,
67 sparql_write_xml_result(Out, ask(TrueFalse), Options).
68sparql_write_xml_result(Out, select(VarTerm, Rows), Options) :-
69 VarTerm =.. [_|VarNames],
70 option(ordered(Ordered), Options, false),
71 option(distinct(Distinct), Options, false),
72 write_header(Out),
73 format(Out, ' <head>~n', []),
74 write_varnames(VarNames, Out),
75 format(Out, ' </head>~n', []),
76 format(Out, ' <results ordered="~w" distinct="~w">~n',
77 [Ordered, Distinct]),
78 write_rows(Rows, VarNames, Out),
79 format(Out, ' </results>~n', []),
80 format(Out, '</sparql>~n', []).
81
(Out) :-
83 xml_encoding(Out, Encoding),
84 format(Out, '<?xml version="1.0" encoding="~w"?>~n', [Encoding]),
85 ns(sparql, Prefix),
86 format(Out, '<sparql xmlns="~w">~n', [Prefix]).
87
88xml_encoding(Out, Encoding) :-
89 stream_property(Out, encoding(Enc)),
90 ( xml_encoding_name(Enc, Encoding)
91 -> true
92 ; throw(error(domain_error(rdf_encoding, Enc), _))
93 ).
94
95xml_encoding_name(ascii, 'US-ASCII').
96xml_encoding_name(iso_latin_1, 'ISO-8859-1').
97xml_encoding_name(utf8, 'UTF-8').
98
99write_varnames([], _).
100write_varnames([H|T], Out) :-
101 stream_property(Out, encoding(Encoding)),
102 xml_quote_attribute(H, Q, Encoding),
103 format(Out, ' <variable name="~w"/>~n', [Q]),
104 write_varnames(T, Out).
105
106write_rows(Rows, VarNames, Out) :-
107 empty_assoc(BNodes),
108 write_rows(Rows, VarNames, Out, state(0, BNodes), _).
109
110write_rows([], _, _, State, State).
111write_rows([H|T], VarNames, Out, State0, State) :-
112 write_row(H, VarNames, Out, State0, State1),
113 write_rows(T, VarNames, Out, State1, State).
114
115write_row(Row, VarNames, Out, State0, State) :-
116 format(Out, ' <result>~n', []),
117 write_bindings(VarNames, 1, Row, Out, State0, State),
118 format(Out, ' </result>~n', []).
119
120write_bindings([], _, _, _, State, State).
121write_bindings([Name|T], I, Row, Out, State0, State) :-
122 arg(I, Row, Value),
123 write_binding(Value, Name, Out, State0, State1),
124 I2 is I + 1,
125 write_bindings(T, I2, Row, Out, State1, State).
126
127write_binding(Var, _, _, S, S) :- var(Var), !.
128write_binding('$null$', _, _, S, S) :- !.
129write_binding(Value, Name, Out, State0, State) :-
130 stream_property(Out, encoding(Encoding)),
131 xml_quote_attribute(Name, Q, Encoding),
132 format(Out, ' <binding name="~w">~n', [Q]),
133 write_binding_value(Value, Out, State0, State),
134 format(Out, ' </binding>~n', []).
135
136write_binding_value(literal(Lit), Out, State, State) :-
137 !,
138 write_binding_literal(Lit, Out).
139write_binding_value(URI, Out, State0, State) :-
140 rdf_is_bnode(URI),
141 !,
142 bnode_id(URI, Id, State0, State),
143 format(Out, ' <bnode>~w</bnode>~n', [Id]).
144write_binding_value(URI, Out, State, State) :-
145 stream_property(Out, encoding(Encoding)),
146 xml_quote_cdata(URI, Q, Encoding),
147 format(Out, ' <uri>~w</uri>~n', [Q]).
156write_binding_literal(type(Type, DOM), Out) :-
157 rdf_equal(Type, rdf:'XMLLiteral'),
158 xml_is_dom(DOM),
159 !,
160 with_output_to(string(S),
161 xml_write(current_output, DOM,
162 [ header(false),
163 layout(false)
164 ])),
165 stream_property(Out, encoding(Encoding)),
166 xml_quote_cdata(S, QV, Encoding),
167 format(Out, ' <literal datatype="~w">~w</literal>~n', [Type, QV]).
168write_binding_literal(type(Type, Value), Out) :-
169 !,
170 stream_property(Out, encoding(Encoding)),
171 xml_quote_attribute(Type, QT, Encoding),
172 ( atom(Value)
173 -> xml_quote_cdata(Value, QV, Encoding)
174 ; QV = Value 175 ),
176 format(Out, ' <literal datatype="~w">~w</literal>~n', [QT, QV]).
177write_binding_literal(lang(L, Value), Out) :-
178 !,
179 stream_property(Out, encoding(Encoding)),
180 xml_quote_cdata(Value, QV, Encoding),
181 format(Out, ' <literal xml:lang="~w">~w</literal>~n', [L, QV]).
182write_binding_literal(Value, Out) :-
183 !,
184 stream_property(Out, encoding(Encoding)),
185 xml_quote_cdata(Value, QV, Encoding),
186 format(Out, ' <literal>~w</literal>~n', [QV]).
187
188bnode_id(URI, Id, State0, State) :-
189 State0 = state(N, Assoc),
190 ( get_assoc(URI, Assoc, Id)
191 -> State = State0
192 ; N2 is N + 1,
193 Id = N2, 194 put_assoc(URI, Assoc, Id, Assoc2),
195 State = state(N2, Assoc2)
196 )