YAZ 5.35.1
sru_facet.c
Go to the documentation of this file.
1/* This file is part of the YAZ toolkit.
2 * Copyright (C) Index Data
3 * See the file LICENSE for details.
4 */
9#if HAVE_CONFIG_H
10#include <config.h>
11#endif
12
13#include <stdlib.h>
14
15#include <yaz/srw.h>
16#include <yaz/wrbuf.h>
17#if YAZ_HAVE_XML2
18#include <libxml/parser.h>
19#include <libxml/tree.h>
20#include <assert.h>
21#endif
22
23#include "sru-p.h"
24#include <yaz/pquery.h>
25#include <yaz/facet.h>
26
27static void insert_field(WRBUF w, const char *field, size_t length,
28 const char *attr)
29{
30 const char *cp0 = wrbuf_cstr(w);
31 const char *cp = cp0;
32
33 while (1)
34 {
35 const char *cp2 = strstr(cp, "@attr 1=");
36 if (!cp2)
37 break;
38 cp = cp2 + 8;
39 if (!strncmp(cp, field, length) &&
40 (cp[length] == ' ' || cp[length] == ',' || cp[length] == '\0'))
41 {
42 /* found the field */
43
44 cp += length;
45 wrbuf_insert(w, cp - cp0, attr, strlen(attr));
46 wrbuf_insert(w, cp - cp0, " ", 1);
47 return;
48 }
49 while (*cp && *cp != ',')
50 cp++;
51 }
52 if (wrbuf_len(w))
53 wrbuf_puts(w, ",");
54 wrbuf_puts(w, "@attr 1=");
55 wrbuf_write(w, field, length);
56 wrbuf_puts(w, " ");
57 wrbuf_puts(w, attr);
58}
59
60void yaz_sru_facet_request(ODR o, Z_FacetList **facetList, const char **limit,
61 const char **start, const char **sort)
62{
63 if (o->direction == ODR_ENCODE)
64 {
65 Z_FacetList *fl = *facetList;
66 if (fl)
67 {
68 WRBUF w_limit = wrbuf_alloc();
69 int general_start = -1;
70 int general_sortorder = -1;
71 int general_limit = -1;
72 int i;
73 for (i = 0; i < fl->num; i++)
74 {
75 struct yaz_facet_attr av;
77 av.start = -1;
78 av.sortorder = -1;
79 av.limit = -1;
81 &av);
82 if (av.errcode == 0)
83 {
84 if (av.limit != -1)
85 {
86 if (av.useattr)
87 {
88 wrbuf_printf(w_limit, "%d:%s", av.limit,
89 av.useattr);
90 wrbuf_puts(w_limit, ",");
91 }
92 else
93 general_limit = av.limit;
94 }
95 if (av.start != -1)
96 general_start = av.start;
97 if (av.sortorder != -1)
98 general_sortorder = av.sortorder;
99 }
100 }
101 if (general_limit != -1)
102 {
103 char tmp[32];
104 sprintf(tmp, "%d,", general_limit);
105 wrbuf_insert(w_limit, 0, tmp, strlen(tmp));
106 }
107 if (wrbuf_len(w_limit) > 1)
108 {
109 wrbuf_cut_right(w_limit, 1);
110 *limit = odr_strdup(o, wrbuf_cstr(w_limit));
111 }
112 if (general_start != -1)
113 {
114 char tmp[32];
115 sprintf(tmp, "%d", general_start);
116 *start = odr_strdup(o, tmp);
117 }
118 if (general_sortorder == 1)
119 {
120 *sort = odr_strdup(o, "alphanumeric");
121 }
122 wrbuf_destroy(w_limit);
123 }
124 }
125 else if (o->direction == ODR_DECODE)
126 {
127 WRBUF w = wrbuf_alloc();
128 int general_limit = -1;
129
130 if (*limit)
131 {
132 const char *cp = *limit;
133 int nor = 0;
134 int val = 0;
135 while (sscanf(cp, "%d%n", &val, &nor) >= 1 && nor > 0)
136 {
137 cp += nor;
138 if (*cp == ':') /* field name follows */
139 {
140 char tmp[40];
141 const char *cp0 = ++cp;
142 while (*cp && *cp != ',')
143 cp++;
144 sprintf(tmp, "@attr 3=%d", val);
145 insert_field(w, cp0, cp - cp0, tmp);
146
147 if (*start && strlen(*start) < 20)
148 {
149 sprintf(tmp, "@attr 4=%s", *start);
150 insert_field(w, cp0, cp - cp0, tmp);
151 }
152 if (*sort && !strcmp(*sort, "alphanumeric"))
153 insert_field(w, cp0, cp - cp0, "@attr 2=1");
154 else
155 insert_field(w, cp0, cp - cp0, "@attr 2=0");
156 }
157 else
158 general_limit = val;
159
160 if (*cp != ',')
161 break;
162 cp++;
163 }
164 }
165 if (*sort || *start || general_limit != -1)
166 {
167 if (wrbuf_len(w))
168 wrbuf_puts(w, ",");
169 if (*sort && !strcmp(*sort, "alphanumeric"))
170 wrbuf_printf(w, " @attr 2=1");
171 else
172 wrbuf_printf(w, " @attr 2=0");
173 if (general_limit != -1)
174 wrbuf_printf(w, " @attr 3=%d", general_limit);
175 if (*start)
176 {
177 wrbuf_printf(w, " @attr 4=%s", *start);
178 }
179 }
180 if (wrbuf_len(w))
181 *facetList = yaz_pqf_parse_facet_list(o, wrbuf_cstr(w));
182 else
183 *facetList = 0;
184 wrbuf_destroy(w);
185 }
186}
187
188#if YAZ_HAVE_XML2
189void yaz_sru_facet_response(ODR o, Z_FacetList **facetList, xmlNodePtr n)
190{
191 if (o->direction == ODR_ENCODE)
192 {
193 Z_FacetList *fl = *facetList;
194 if (fl)
195 {
196 int i;
197 const char *ns =
198 "http://docs.oasis-open.org/ns/search-ws/facetedResults";
199 xmlNode *p1 = xmlNewChild(n, 0, BAD_CAST "facetedResults", 0);
200 xmlNsPtr ns_fr = xmlNewNs(p1, BAD_CAST ns, BAD_CAST "fr");
201 for (i = 0; i < fl->num; i++)
202 {
203 Z_FacetField *ff = fl->elements[i];
204 xmlNode *p2 = xmlNewChild(p1, ns_fr, BAD_CAST "facet", 0);
205 int j;
206 xmlNode *p3;
207 struct yaz_facet_attr av;
210 add_xsd_string(p2, "index", av.useattr);
211 p3 = xmlNewChild(p2, 0, BAD_CAST "terms", 0);
212 for (j = 0; j < ff->num_terms; j++)
213 {
214 Z_FacetTerm *ft = ff->terms[j];
215 Z_Term *zt = ft->term;
216 xmlNode *p4 = xmlNewChild(p3, 0, BAD_CAST "term", 0);
217 if (zt->which == Z_Term_general)
218 add_xsd_string_n(p4, "actualTerm",
219 (char *) zt->u.general->buf,
220 zt->u.general->len);
221 if (ft->count)
222 add_xsd_integer(p4, "count", ft->count);
223 }
224 }
225 }
226 }
227 else if (o->direction == ODR_DECODE)
228 {
229 Z_FacetList *fl = (Z_FacetList *) odr_malloc(o, sizeof(*fl));
230 xmlNode *p1;
231
232 fl->num = 0;
233 for (p1 = n->children; p1; p1 = p1->next)
234 if (yaz_match_xsd_element(p1, "facet"))
235 fl->num++;
236 if (fl->num > 0)
237 {
238 int i = 0;
239 *facetList = fl;
240 fl->elements = (Z_FacetField **)
241 odr_malloc(o, sizeof(*fl->elements) * fl->num);
242 for (p1 = n->children; p1; p1 = p1->next)
243 if (yaz_match_xsd_element(p1, "facet"))
244 {
245 char *index_name = 0;
246 xmlNode *p_terms = 0;
247 xmlNode *p2 = p1->children;
248 Z_FacetField *ff = (Z_FacetField *)
249 odr_malloc(o, sizeof(*ff));
250 fl->elements[i++] = ff;
251 ff->attributes = 0;
252 ff->num_terms = 0;
253 ff->terms = 0;
254 for (; p2; p2 = p2->next)
255 {
256 if (yaz_match_xsd_string(p2, "index", o, &index_name))
257 ;
258 else if (yaz_match_xsd_element(p2, "terms"))
259 p_terms = p2;
260 }
261 if (index_name)
262 ff->attributes =
263 zget_AttributeList_use_string(o, index_name);
264 if (p_terms)
265 {
266 xmlNode *p;
267 int i = 0;
268 for (p = p_terms->children; p; p = p->next)
269 {
270 if (yaz_match_xsd_element(p, "term"))
271 ff->num_terms++;
272 }
273 if (ff->num_terms)
274 ff->terms = (Z_FacetTerm **)
275 odr_malloc(o,
276 sizeof(*ff->terms) * ff->num_terms);
277 for (p = p_terms->children; p; p = p->next)
278 {
279 if (yaz_match_xsd_element(p, "term"))
280 {
281 char *cstr = 0;
282 Odr_int *count = 0;
283 xmlNode *p2 = p->children;
284 for (; p2; p2 = p2->next)
285 {
286 if (yaz_match_xsd_string(p2, "actualTerm", o,
287 &cstr))
288 ;
289 else if (yaz_match_xsd_integer(p2, "count", o,
290 &count))
291 ;
292 else
293 ;
294 }
295 if (cstr && count)
296 {
297 ff->terms[i++] =
298 facet_term_create_cstr(o, cstr, *count);
299 }
300 }
301 }
302 ff->num_terms = i;
303 if (ff->num_terms == 0)
304 ff->terms = 0;
305 }
306 }
307
308 }
309 }
310}
311
312#endif
313
314
315/*
316 * Local variables:
317 * c-basic-offset: 4
318 * c-file-style: "Stroustrup"
319 * indent-tabs-mode: nil
320 * End:
321 * vim: shiftwidth=4 tabstop=8 expandtab
322 */
323
Z_FacetTerm * facet_term_create_cstr(ODR odr, const char *cstr, Odr_int freq)
Definition facet.c:189
void yaz_facet_attr_init(struct yaz_facet_attr *attr_values)
Definition facet.c:68
void yaz_facet_attr_get_z_attributes(const Z_AttributeList *attributes, struct yaz_facet_attr *av)
Definition facet.c:147
Header for the facet utilities.
#define ODR_DECODE
Definition odr.h:95
nmem_int_t Odr_int
Definition odr.h:47
#define ODR_ENCODE
Definition odr.h:96
void * odr_malloc(ODR o, size_t size)
Definition odr_mem.c:31
char * odr_strdup(ODR o, const char *str)
Definition odr_mem.c:36
Z_FacetList * yaz_pqf_parse_facet_list(ODR o, const char *qbuf)
Definition pquery.c:882
Z_AttributeList * zget_AttributeList_use_string(ODR o, const char *name)
creates AttributeList with type=1(use) and string value
Definition pquery.c:310
Header for PQF parsing.
SRU private header.
int yaz_match_xsd_element(xmlNodePtr ptr, const char *elem)
Definition xml_match.c:17
void add_xsd_integer(xmlNodePtr ptr, const char *elem, const Odr_int *val)
Definition xml_add.c:66
xmlNodePtr add_xsd_string(xmlNodePtr ptr, const char *elem, const char *val)
Definition xml_add.c:61
int yaz_match_xsd_string(xmlNodePtr ptr, const char *elem, ODR o, char **val)
Definition xml_match.c:71
xmlNodePtr add_xsd_string_n(xmlNodePtr ptr, const char *elem, const char *val, int len)
Definition xml_add.c:35
int yaz_match_xsd_integer(xmlNodePtr ptr, const char *elem, ODR o, Odr_int **val)
Definition xml_match.c:126
void yaz_sru_facet_request(ODR o, Z_FacetList **facetList, const char **limit, const char **start, const char **sort)
Definition sru_facet.c:60
void yaz_sru_facet_response(ODR o, Z_FacetList **facetList, xmlNodePtr n)
Definition sru_facet.c:189
static void insert_field(WRBUF w, const char *field, size_t length, const char *attr)
Definition sru_facet.c:27
Header for SRW/SRU.
Z_AttributeList * attributes
Definition z-facet-1.h:36
Z_FacetTerm ** terms
Definition z-facet-1.h:38
Z_FacetField ** elements
Definition z-facet-1.h:32
Odr_int * count
Definition z-facet-1.h:43
Z_Term * term
Definition z-facet-1.h:42
Odr_oct * general
Definition z-core.h:539
union Z_Term::@48 u
int which
Definition z-core.h:537
int len
Definition odr.h:102
char * buf
Definition odr.h:101
Definition odr.h:125
int direction
Definition odr.h:126
string buffer
Definition wrbuf.h:43
int sortorder
Definition facet.h:60
const char * useattr
Definition facet.h:56
int errcode
Definition facet.h:54
void wrbuf_destroy(WRBUF b)
destroy WRBUF and its buffer
Definition wrbuf.c:38
void wrbuf_insert(WRBUF b, size_t pos, const char *buf, size_t size)
inserts buffer into WRBUF at some position
Definition wrbuf.c:78
const char * wrbuf_cstr(WRBUF b)
returns WRBUF content as C-string
Definition wrbuf.c:299
WRBUF wrbuf_alloc(void)
construct WRBUF
Definition wrbuf.c:25
void wrbuf_printf(WRBUF b, const char *fmt,...)
writes printf result to WRBUF
Definition wrbuf.c:189
void wrbuf_cut_right(WRBUF b, size_t no_to_remove)
cut size of WRBUF
Definition wrbuf.c:315
void wrbuf_puts(WRBUF b, const char *buf)
appends C-string to WRBUF
Definition wrbuf.c:89
void wrbuf_write(WRBUF b, const char *buf, size_t size)
append constant size buffer to WRBUF
Definition wrbuf.c:68
Header for WRBUF (growing buffer)
#define wrbuf_len(b)
Definition wrbuf.h:269
#define Z_Term_general
Definition z-core.h:547