+Added a facility to embed metadata for records generated by the DOM XML
+filter. The meta data step is triggered by a 'meta' section in the
+retrieve section of the dom config, e.g.
+ <retrieve name="myelementset">
+ <xslt stylesheet="my-usual.xsl"/>
+ <meta/>
+ </retrieve>
+The meta section substitutes metadata for all elements called 'meta' in
+namespace http://indexdata.com/zebra-2.0 . The meta element must have
+exactly one attribute, element_set_name, which specifies the special
+element set name which is equivalent to the suffix to zebra:: for
+non-embedded special retrievals. This allows snippets, facets etc to be
+included.
+
--- 2.0.32 2008/06/06
Fixed OAI example.
int rec_len;
int diagnostic;
char * addinfo;
+
+ /* special fetch to be included in retrieved response (say snippets) */
+ void *handle;
+ int (*special_fetch)(void *handle, const char *esn,
+ const Odr_oid *input_format,
+ const Odr_oid **output_format,
+ WRBUF result, WRBUF addinfo);
};
typedef struct recType *RecType;
#define ZEBRA_PI_NAME "zebra-2.0"
static const char *zebra_pi_name = ZEBRA_PI_NAME;
+enum convert_type {
+ convert_xslt_type,
+ convert_meta_type
+};
-
-struct convert_s {
+struct convert_xslt {
const char *stylesheet;
xsltStylesheetPtr stylesheet_xsp;
+};
+
+struct convert_meta {
+ int dummy;
+};
+
+struct convert_s {
+ enum convert_type which;
+ union {
+ struct convert_xslt xslt;
+ struct convert_meta meta;
+ } u;
struct convert_s *next;
};
char *fname;
char *full_name;
const char *profile_path;
- ODR odr_record;
- ODR odr_config;
+ NMEM nmem_record;
+ NMEM nmem_config;
xmlDocPtr doc_config;
struct filter_extract *extract;
struct filter_retrieve *retrieve_list;
static void set_param_str(const char **params, const char *name,
- const char *value, ODR odr)
+ const char *value, NMEM nmem)
{
- char *quoted = odr_malloc(odr, 3 + strlen(value));
+ char *quoted = nmem_malloc(nmem, 3 + strlen(value));
sprintf(quoted, "'%s'", value);
while (*params)
params++;
}
static void set_param_int(const char **params, const char *name,
- zint value, ODR odr)
+ zint value, NMEM nmem)
{
- char *quoted = odr_malloc(odr, 30); /* 25 digits enough for 2^64 */
+ char *quoted = nmem_malloc(nmem, 30); /* 25 digits enough for 2^64 */
while (*params)
params++;
sprintf(quoted, "'" ZINT_FORMAT "'", value);
tinfo->fname = 0;
tinfo->full_name = 0;
tinfo->profile_path = 0;
- tinfo->odr_record = odr_createmem(ODR_ENCODE);
- tinfo->odr_config = odr_createmem(ODR_ENCODE);
+ tinfo->nmem_record = nmem_create();
+ tinfo->nmem_config = nmem_create();
tinfo->extract = 0;
tinfo->retrieve_list = 0;
tinfo->input_list = 0;
return 0;
}
+static int attr_content_xml(struct _xmlAttr *attr, const char *name,
+ const char **dst_content)
+{
+ if (0 == XML_STRCMP(attr->name, name) && attr->children
+ && attr->children->type == XML_TEXT_NODE)
+ {
+ *dst_content = (const char *) (attr->children->content);
+ return 1;
+ }
+ return 0;
+}
+
static void destroy_xsp(struct convert_s *c)
{
- while(c)
+ while (c)
{
- if (c->stylesheet_xsp)
- xsltFreeStylesheet(c->stylesheet_xsp);
+ if (c->which == convert_xslt_type)
+ {
+ if (c->u.xslt.stylesheet_xsp)
+ xsltFreeStylesheet(c->u.xslt.stylesheet_xsp);
+ }
c = c->next;
}
}
xmlFreeDoc(tinfo->doc_config);
tinfo->doc_config = 0;
}
- odr_reset(tinfo->odr_config);
+ nmem_reset(tinfo->nmem_config);
}
static ZEBRA_RES parse_convert(struct filter_info *tinfo, xmlNodePtr ptr,
if (!XML_STRCMP(ptr->name, "xslt"))
{
struct _xmlAttr *attr;
- struct convert_s *p
- = odr_malloc(tinfo->odr_config, sizeof(*p));
+ struct convert_s *p = nmem_malloc(tinfo->nmem_config, sizeof(*p));
p->next = 0;
- p->stylesheet = 0;
- p->stylesheet_xsp = 0;
+ p->which = convert_xslt_type;
+ p->u.xslt.stylesheet = 0;
+ p->u.xslt.stylesheet_xsp = 0;
for (attr = ptr->properties; attr; attr = attr->next)
- if (attr_content(attr, "stylesheet", &p->stylesheet))
+ if (attr_content(attr, "stylesheet", &p->u.xslt.stylesheet))
;
else
{
dom_log(YLOG_WARN, tinfo, ptr,
"bad attribute @%s", attr->name);
}
- if (p->stylesheet)
+ if (p->u.xslt.stylesheet)
{
char tmp_xslt_full_name[1024];
- if (!yaz_filepath_resolve(p->stylesheet,
+ if (!yaz_filepath_resolve(p->u.xslt.stylesheet,
tinfo->profile_path,
NULL,
tmp_xslt_full_name))
dom_log(YLOG_WARN, tinfo, 0,
"stylesheet %s not found in "
"path %s",
- p->stylesheet,
+ p->u.xslt.stylesheet,
tinfo->profile_path);
return ZEBRA_FAIL;
}
- p->stylesheet_xsp
+ p->u.xslt.stylesheet_xsp
= xsltParseStylesheetFile((const xmlChar*)
tmp_xslt_full_name);
- if (!p->stylesheet_xsp)
+ if (!p->u.xslt.stylesheet_xsp)
{
dom_log(YLOG_WARN, tinfo, 0,
"could not parse xslt stylesheet %s",
tmp_xslt_full_name);
return ZEBRA_FAIL;
}
- }
- else
- {
- dom_log(YLOG_WARN, tinfo, ptr,
- "missing attribute 'stylesheet' ");
- return ZEBRA_FAIL;
- }
- *l = p;
- l = &p->next;
+ }
+ else
+ {
+ dom_log(YLOG_WARN, tinfo, ptr,
+ "missing attribute 'stylesheet'");
+ return ZEBRA_FAIL;
+ }
+ *l = p;
+ l = &p->next;
+ }
+ else if (!XML_STRCMP(ptr->name, "meta"))
+ {
+ struct _xmlAttr *attr;
+ struct convert_s *p = nmem_malloc(tinfo->nmem_config, sizeof(*p));
+
+ p->next = 0;
+ p->which = convert_meta_type;
+
+ for (attr = ptr->properties; attr; attr = attr->next)
+ dom_log(YLOG_WARN, tinfo, ptr,
+ "bad attribute @%s", attr->name);
+ *l = p;
+ l = &p->next;
}
else
{
return ZEBRA_OK;
}
+static int process_meta(struct filter_info *tinfo, xmlDocPtr doc, xmlNodePtr node,
+ struct recRetrieveCtrl *retctr)
+{
+
+ if (node->type == XML_ELEMENT_NODE && node->ns && node->ns->href &&
+ 0 == XML_STRCMP(node->ns->href, zebra_dom_ns))
+ {
+ if (0 == XML_STRCMP(node->name, "meta"))
+ {
+ const char *element_set_name = 0;
+
+ struct _xmlAttr *attr;
+ for (attr = node->properties; attr; attr = attr->next)
+ {
+ if (attr_content_xml(attr, "element_set_name", &element_set_name))
+ ;
+ else
+ {
+ dom_log(YLOG_WARN, tinfo, node,
+ "bad attribute @%s, expected @element_set_name",
+ attr->name);
+ }
+ }
+ if (element_set_name)
+ {
+ WRBUF result = wrbuf_alloc();
+ WRBUF addinfo = wrbuf_alloc();
+ const Odr_oid *input_format = yaz_oid_recsyn_xml;
+ const Odr_oid *output_format = 0;
+ int ret;
+
+ ret = retctr->special_fetch(retctr->handle,
+ element_set_name,
+ input_format, &output_format,
+ result, addinfo);
+ if (ret == 0)
+ {
+ xmlDocPtr sub_doc =
+ xmlParseMemory( wrbuf_buf(result), wrbuf_len(result));
+ if (sub_doc)
+ {
+ xmlNodePtr t = xmlDocGetRootElement(sub_doc);
+ xmlAddChild(node, xmlCopyNode(t, 1));
+ xmlFreeDoc(sub_doc);
+ }
+ }
+ wrbuf_destroy(result);
+ wrbuf_destroy(addinfo);
+ }
+ }
+ }
+ for (node = node->children; node; node = node->next)
+ process_meta(tinfo, doc, node, retctr);
+ return 0;
+}
+
static ZEBRA_RES perform_convert(struct filter_info *tinfo,
struct recExtractCtrl *extctr,
+ struct recRetrieveCtrl *retctr,
struct convert_s *convert,
const char **params,
xmlDocPtr *doc,
{
for (; convert; convert = convert->next)
{
- xmlChar *buf_out = 0;
- int len_out = 0;
- xmlDocPtr res_doc = xsltApplyStylesheet(convert->stylesheet_xsp,
- *doc, params);
- if (last_xsp)
- *last_xsp = convert->stylesheet_xsp;
-
- if (!res_doc)
- break;
-
- /* now saving into buffer and re-reading into DOM to avoid annoing
- XSLT problem with thrown-out indentation text nodes */
- xsltSaveResultToString(&buf_out, &len_out, res_doc,
- convert->stylesheet_xsp);
- xmlFreeDoc(res_doc);
-
- xmlFreeDoc(*doc);
-
- *doc = xmlParseMemory((const char *) buf_out, len_out);
+ if (convert->which == convert_xslt_type)
+ {
+ xmlChar *buf_out = 0;
+ int len_out = 0;
+ xmlDocPtr res_doc = xsltApplyStylesheet(convert->u.xslt.stylesheet_xsp,
+ *doc, params);
+ if (last_xsp)
+ *last_xsp = convert->u.xslt.stylesheet_xsp;
+
+ if (!res_doc)
+ break;
+
+ /* now saving into buffer and re-reading into DOM to avoid annoing
+ XSLT problem with thrown-out indentation text nodes */
+ xsltSaveResultToString(&buf_out, &len_out, res_doc,
+ convert->u.xslt.stylesheet_xsp);
+ xmlFreeDoc(res_doc);
+
+ xmlFreeDoc(*doc);
+
+ *doc = xmlParseMemory((const char *) buf_out, len_out);
+
+ /* writing debug info out */
+ if (extctr && extctr->flagShowRecords)
+ yaz_log(YLOG_LOG, "%s: XSLT %s\n %.*s",
+ tinfo->fname ? tinfo->fname : "(none)",
+ convert->u.xslt.stylesheet,
+ len_out, buf_out);
+
+ xmlFree(buf_out);
+ }
+ else if (convert->which == convert_meta_type)
+ {
+ if (retctr) /* only execute meta on retrieval */
+ {
+ process_meta(tinfo, *doc, xmlDocGetRootElement(*doc), retctr);
- /* writing debug info out */
- if (extctr && extctr->flagShowRecords)
- yaz_log(YLOG_LOG, "%s: XSLT %s\n %.*s",
- tinfo->fname ? tinfo->fname : "(none)",
- convert->stylesheet,
- len_out, buf_out);
-
- xmlFree(buf_out);
+ /* last stylesheet absent */
+ if (last_xsp)
+ *last_xsp = 0;
+ }
+ }
}
return ZEBRA_OK;
}
struct filter_input **np = &tinfo->input_list;
for (;*np; np = &(*np)->next)
;
- p = *np = odr_malloc(tinfo->odr_config, sizeof(*p));
+ p = *np = nmem_malloc(tinfo->nmem_config, sizeof(*p));
p->next = 0;
p->syntax = 0;
p->name = 0;
xmlNodePtr ptr;
xmlDocPtr doc;
- tinfo->fname = odr_strdup(tinfo->odr_config, fname);
+ tinfo->fname = nmem_strdup(tinfo->nmem_config, fname);
if (yaz_filepath_resolve(tinfo->fname, tinfo->profile_path,
NULL, tmp_full_name))
- tinfo->full_name = odr_strdup(tinfo->odr_config, tmp_full_name);
+ tinfo->full_name = nmem_strdup(tinfo->nmem_config, tmp_full_name);
else
- tinfo->full_name = odr_strdup(tinfo->odr_config, tinfo->fname);
+ tinfo->full_name = nmem_strdup(tinfo->nmem_config, tinfo->fname);
yaz_log(YLOG_LOG, "%s dom filter: "
"loading config file %s", tinfo->fname, tinfo->full_name);
*/
struct _xmlAttr *attr;
struct filter_extract *f =
- odr_malloc(tinfo->odr_config, sizeof(*f));
+ nmem_malloc(tinfo->nmem_config, sizeof(*f));
tinfo->extract = f;
f->name = 0;
struct _xmlAttr *attr;
struct filter_retrieve **fp = &tinfo->retrieve_list;
struct filter_retrieve *f =
- odr_malloc(tinfo->odr_config, sizeof(*f));
+ nmem_malloc(tinfo->nmem_config, sizeof(*f));
while (*fp)
fp = &(*fp)->next;
</retrieve>
*/
struct filter_store *f =
- odr_malloc(tinfo->odr_config, sizeof(*f));
+ nmem_malloc(tinfo->nmem_config, sizeof(*f));
tinfo->store = f;
f->convert = 0;
{
struct filter_info *tinfo = clientData;
destroy_dom(tinfo);
- odr_destroy(tinfo->odr_config);
- odr_destroy(tinfo->odr_record);
+ nmem_destroy(tinfo->nmem_config);
+ nmem_destroy(tinfo->nmem_record);
xfree(tinfo);
}
}
-/* DOM filter style indexing */
-static int attr_content_xml(struct _xmlAttr *attr, const char *name,
- const char **dst_content)
-{
- if (0 == XML_STRCMP(attr->name, name) && attr->children
- && attr->children->type == XML_TEXT_NODE)
- {
- *dst_content = (const char *) (attr->children->content);
- return 1;
- }
- return 0;
-}
-
/* DOM filter style indexing */
static void index_value_of(struct filter_info *tinfo,
/* actually indexing the text given */
recword->index_name = (const char *)index;
- if (type && *type)
+ if (*type)
recword->index_type = (const char *) type;
/* writing debug out */
if (extctr->flagShowRecords)
dom_log(YLOG_LOG, tinfo, 0,
"INDEX '%s:%s' '%s'",
- index ? (const char *) index : "null",
- type ? (const char *) type : "null",
- text ? (const char *) text : "null");
+ (const char *) index,
+ (const char *) type,
+ (const char *) text);
(extctr->tokenAdd)(recword);
if (node->type == XML_ELEMENT_NODE && node->ns && node->ns->href
&& 0 == XML_STRCMP(node->ns->href, zebra_dom_ns))
{
- if (0 == XML_STRCMP(node->name, "index"))
- {
+ if (0 == XML_STRCMP(node->name, "index"))
+ {
const char *index_p = 0;
struct _xmlAttr *attr;
}
-
-
static int convert_extract_doc(struct filter_info *tinfo,
struct filter_input *input,
struct recExtractCtrl *p,
xmlDocPtr doc)
-
{
xmlChar *buf_out;
int len_out;
/* we actuallu have a document which needs to be processed further */
params[0] = 0;
- set_param_str(params, "schema", zebra_dom_ns, tinfo->odr_record);
+ set_param_str(params, "schema", zebra_dom_ns, tinfo->nmem_record);
if (p && p->flagShowRecords)
{
}
/* input conversion */
- perform_convert(tinfo, p, input->convert, params, &doc, 0);
-
+ perform_convert(tinfo, p, 0, input->convert, params, &doc, 0);
if (tinfo->store)
{
/* store conversion */
store_doc = xmlCopyDoc(doc, 1);
- perform_convert(tinfo, p, tinfo->store->convert,
+ perform_convert(tinfo, p, 0, tinfo->store->convert,
params, &store_doc, &last_xsp);
}
xmlFreeDoc(store_doc);
/* extract conversion */
- perform_convert(tinfo, p, tinfo->extract->convert, params, &doc, 0);
+ perform_convert(tinfo, p, 0, tinfo->extract->convert, params, &doc, 0);
/* finally, do the indexing */
if (!input)
return RECCTRL_EXTRACT_ERROR_GENERIC;
- odr_reset(tinfo->odr_record);
+ nmem_reset(tinfo->nmem_record);
if (p->setStoreData == 0)
return extract_xml_full(tinfo, input, p);
return 0;
}
-static int filter_retrieve (void *clientData, struct recRetrieveCtrl *p)
+static int filter_retrieve(void *clientData, struct recRetrieveCtrl *p)
{
/* const char *esn = zebra_dom_ns; */
const char *esn = 0;
}
params[0] = 0;
- set_param_int(params, "id", p->localno, p->odr);
+ set_param_int(params, "id", p->localno, p->odr->mem);
if (p->fname)
- set_param_str(params, "filename", p->fname, p->odr);
+ set_param_str(params, "filename", p->fname, p->odr->mem);
if (p->staticrank >= 0)
- set_param_int(params, "rank", p->staticrank, p->odr);
+ set_param_int(params, "rank", p->staticrank, p->odr->mem);
if (esn)
- set_param_str(params, "schema", esn, p->odr);
+ set_param_str(params, "schema", esn, p->odr->mem);
else
if (retrieve->name)
- set_param_str(params, "schema", retrieve->name, p->odr);
+ set_param_str(params, "schema", retrieve->name, p->odr->mem);
else if (retrieve->identifier)
- set_param_str(params, "schema", retrieve->identifier, p->odr);
+ set_param_str(params, "schema", retrieve->identifier, p->odr->mem);
else
- set_param_str(params, "schema", "", p->odr);
+ set_param_str(params, "schema", "", p->odr->mem);
if (p->score >= 0)
- set_param_int(params, "score", p->score, p->odr);
- set_param_int(params, "size", p->recordSize, p->odr);
+ set_param_int(params, "score", p->score, p->odr->mem);
+ set_param_int(params, "size", p->recordSize, p->odr->mem);
doc = xmlReadIO(ioread_ret, ioclose_ret, p /* I/O handler */,
0 /* URL */,
}
/* retrieve conversion */
- perform_convert(tinfo, 0, retrieve->convert, params, &doc, &last_xsp);
+ perform_convert(tinfo, 0, p, retrieve->convert, params, &doc, &last_xsp);
if (!doc)
{
p->diagnostic = YAZ_BIB1_SYSTEM_ERROR_IN_PRESENTING_RECORDS;
#define ZEBRA_XML_HEADER_STR "<record xmlns=\"http://www.indexdata.com/zebra/\""
+struct special_fetch_s {
+ ZebraHandle zh;
+ const char *setname;
+ zint sysno;
+ int score;
+ NMEM nmem;
+};
+
static int zebra_create_record_stream(ZebraHandle zh,
Record *rec,
struct ZebraRecStream *stream)
}
-int zebra_special_sort_fetch(ZebraHandle zh, zint sysno, ODR odr,
- const char *elemsetname,
- const Odr_oid *input_format,
- const Odr_oid **output_format,
- char **rec_bufp, int *rec_lenp)
+int zebra_special_sort_fetch(
+ struct special_fetch_s *fi, const char *elemsetname,
+ const Odr_oid *input_format,
+ const Odr_oid **output_format,
+ WRBUF result, WRBUF addinfo)
{
const char *retrieval_index;
size_t retrieval_index_len;
char retrieval_index_cstr[256];
char retrieval_type_cstr[256];
int ord;
+ ZebraHandle zh = fi->zh;
/* only accept XML and SUTRS requests */
if (oid_oidcmp(input_format, yaz_oid_recsyn_xml)
const char *index_type;
const char *db = 0;
const char *string_index = 0;
- WRBUF wrbuf = wrbuf_alloc();
+ WRBUF wrbuf = result;
- zebra_sort_sysno(zh->reg->sort_index, sysno);
+ zebra_sort_sysno(zh->reg->sort_index, fi->sysno);
zebra_sort_type(zh->reg->sort_index, ord);
zebra_sort_read(zh->reg->sort_index, str);
wrbuf_printf(wrbuf, ZEBRA_XML_HEADER_STR
" sysno=\"" ZINT_FORMAT "\""
" set=\"zebra::index%s/\">\n",
- sysno, elemsetname);
+ fi->sysno, elemsetname);
wrbuf_printf(wrbuf, " <index name=\"%s\"",
string_index);
wrbuf_printf(wrbuf, "%s %s %s\n", string_index, index_type,
dst_buf);
}
- *rec_lenp = wrbuf_len(wrbuf);
- *rec_bufp = odr_malloc(odr, *rec_lenp);
- memcpy(*rec_bufp, wrbuf_buf(wrbuf), *rec_lenp);
- wrbuf_destroy(wrbuf);
return 0;
}
}
-int zebra_special_index_fetch(ZebraHandle zh, zint sysno, ODR odr,
- Record rec,
- const char *elemsetname,
- const Odr_oid *input_format,
- const Odr_oid **output_format,
- char **rec_bufp, int *rec_lenp)
+int zebra_special_index_fetch(
+ struct special_fetch_s *fi, const char *elemsetname,
+ const Odr_oid *input_format,
+ const Odr_oid **output_format,
+ WRBUF result, WRBUF addinfo,
+ Record rec)
{
const char *retrieval_index;
size_t retrieval_index_len;
zebra_rec_keys_t keys;
int ret_code = 0;
char retrieval_type_cstr[256];
+ ZebraHandle zh = fi->zh;
/* set output variables before processing possible error states */
/* *rec_lenp = 0; */
size_t slen;
const char *str;
struct it_key key_in;
- WRBUF wrbuf = wrbuf_alloc();
+ WRBUF wrbuf = result;
if (!oid_oidcmp(input_format, yaz_oid_recsyn_xml))
{
wrbuf_printf(wrbuf, ZEBRA_XML_HEADER_STR
" sysno=\"" ZINT_FORMAT "\""
" set=\"zebra::index%s/\">\n",
- sysno, elemsetname);
+ fi->sysno, elemsetname);
}
else if (!oid_oidcmp(input_format, yaz_oid_recsyn_sutrs))
*output_format = input_format;
}
if (!oid_oidcmp(input_format, yaz_oid_recsyn_xml))
wrbuf_printf(wrbuf, "</record>\n");
- *rec_lenp = wrbuf_len(wrbuf);
- *rec_bufp = odr_malloc(odr, *rec_lenp);
- memcpy(*rec_bufp, wrbuf_buf(wrbuf), *rec_lenp);
- wrbuf_destroy(wrbuf);
}
zebra_rec_keys_close(keys);
return ret_code;
return return_code;
}
-static int snippet_fetch(ZebraHandle zh, const char *setname,
- zint sysno, ODR odr,
- const char *elemsetname,
- const Odr_oid *input_format,
- const Odr_oid **output_format,
- char **rec_bufp, int *rec_lenp)
+static int snippet_fetch(
+ struct special_fetch_s *fi, const char *elemsetname,
+ const Odr_oid *input_format,
+ const Odr_oid **output_format,
+ WRBUF result, WRBUF addinfo)
{
+ ZebraHandle zh = fi->zh;
zebra_snippets *rec_snippets = zebra_snippets_create();
- int return_code = zebra_get_rec_snippets(zh, sysno, rec_snippets);
+ int return_code = zebra_get_rec_snippets(zh, fi->sysno, rec_snippets);
if (!return_code)
{
- WRBUF wrbuf = wrbuf_alloc();
+ WRBUF wrbuf = result;
zebra_snippets *hit_snippet = zebra_snippets_create();
- zebra_snippets_hit_vector(zh, setname, sysno, hit_snippet);
+ zebra_snippets_hit_vector(zh, fi->setname, fi->sysno, hit_snippet);
#if 0
/* for debugging purposes */
*output_format = yaz_oid_recsyn_xml;
- if (return_code == 0)
- {
- *rec_lenp = wrbuf_len(wrbuf);
- *rec_bufp = odr_strdup(odr, wrbuf_cstr(wrbuf));
- }
- wrbuf_destroy(wrbuf);
zebra_snippets_destroy(hit_snippet);
}
zebra_snippets_destroy(rec_snippets);
return col;
}
-static ZEBRA_RES facet_fetch(ZebraHandle zh, const char *setname,
- ODR odr,
- const char *elemsetname,
- const Odr_oid *input_format,
- const Odr_oid **output_format,
- char **rec_bufp, int *rec_lenp)
+static ZEBRA_RES facet_fetch(
+ struct special_fetch_s *fi, const char *elemsetname,
+ const Odr_oid *input_format,
+ const Odr_oid **output_format,
+ WRBUF result, WRBUF addinfo)
{
zint *pos_array;
int i;
ZebraMetaRecord *poset;
ZEBRA_RES ret = ZEBRA_OK;
int *ord_array;
- WRBUF wr = wrbuf_alloc();
+ WRBUF wr = result;
int use_xml = 0;
int no_ord = 0;
struct index_spec *spec, *spec_list;
int error;
+ ZebraHandle zh = fi->zh;
res_get_int(zh->res, "facetNumRecs", &num_recs);
res_get_int(zh->res, "facetMaxChunks", &max_chunks);
if (oid_oidcmp(input_format, yaz_oid_recsyn_xml) == 0)
use_xml = 1;
- spec_list = parse_index_spec(elemsetname, odr_getmem(odr), &error);
+ spec_list = parse_index_spec(elemsetname, fi->nmem, &error);
if (!spec_list || error)
{
no_ord++;
}
- ord_array = odr_malloc(odr, sizeof(*ord_array) * no_ord);
+ ord_array = nmem_malloc(fi->nmem, sizeof(*ord_array) * no_ord);
for (spec = spec_list, i = 0; spec; spec = spec->next, i++)
{
}
ord_array[i] = ord;
}
- pos_array = (zint *) odr_malloc(odr, num_recs * sizeof(*pos_array));
+ pos_array = (zint *) nmem_malloc(fi->nmem, num_recs * sizeof(*pos_array));
for (i = 0; i < num_recs; i++)
pos_array[i] = i+1;
- poset = zebra_meta_records_create(zh, setname, num_recs, pos_array);
+ poset = zebra_meta_records_create(zh, fi->setname, num_recs, pos_array);
if (!poset)
{
zebra_setError(zh, YAZ_BIB1_SPECIFIED_RESULT_SET_DOES_NOT_EXIST,
- setname);
+ fi->setname);
ret = ZEBRA_FAIL;
}
else
{
yaz_timing_t timing = yaz_timing_create();
zebra_strmap_t *map_array
- = odr_malloc(odr, sizeof *map_array * no_ord);
+ = nmem_malloc(fi->nmem, sizeof *map_array * no_ord);
for (i = 0; i < no_ord; i++)
map_array[i] = zebra_strmap_create();
int no_sysnos = MAX_SYSNOS_PER_RECORD;
if (!poset[i].sysno)
continue;
- ret = zebra_result_recid_to_sysno(zh, setname,
+ ret = zebra_result_recid_to_sysno(zh, fi->setname,
poset[i].sysno,
sysnos, &no_sysnos);
assert(no_sysnos > 0);
no_collect_terms = 1;
col = term_collect_create(map_array[i], no_collect_terms, nmem);
term_collect_freq(zh, col, no_collect_terms, ord_array[i],
- resultSetRef(zh, setname));
+ resultSetRef(zh, fi->setname));
if (use_xml)
wrbuf_printf(wr, " <facet type=\"%s\" index=\"%s\">\n",
yaz_timing_get_real(timing));
yaz_timing_destroy(&timing);
}
- *rec_bufp = odr_strdup(odr, wrbuf_cstr(wr));
- wrbuf_destroy(wr);
- *rec_lenp = strlen(*rec_bufp);
*output_format = yaz_oid_recsyn_xml;
-
zebra_meta_records_destroy(zh, poset, num_recs);
return ret;
}
-int zebra_special_fetch(ZebraHandle zh, const char *setname,
- zint sysno, int score, ODR odr,
- const char *elemsetname,
- const Odr_oid *input_format,
- const Odr_oid **output_format,
- char **rec_bufp, int *rec_lenp)
+
+int zebra_special_fetch(
+ void *handle, const char *elemsetname,
+ const Odr_oid *input_format,
+ const Odr_oid **output_format,
+ WRBUF result, WRBUF addinfo
+ )
{
- Record rec;
+ Record rec = 0;
+ struct special_fetch_s *fi = (struct special_fetch_s *) handle;
+ ZebraHandle zh = fi->zh;
+ zint sysno = fi->sysno;
/* set output variables before processing possible error states */
/* *rec_lenp = 0; */
if (elemsetname && 0 == strncmp(elemsetname, "facet", 5))
{
- return facet_fetch(zh, setname, odr,
- elemsetname + 5,
+ return facet_fetch(fi, elemsetname + 5,
input_format, output_format,
- rec_bufp, rec_lenp);
+ result, addinfo);
}
if (elemsetname && 0 == strcmp(elemsetname, "snippet"))
{
- return snippet_fetch(zh, setname, sysno, odr,
- elemsetname + 7,
+ return snippet_fetch(fi, elemsetname + 7,
input_format, output_format,
- rec_bufp, rec_lenp);
+ result, addinfo);
}
/* processing zebra::meta::sysno elemset without fetching binary data */
if (elemsetname && 0 == strcmp(elemsetname, "meta::sysno"))
{
int ret = 0;
- WRBUF wrbuf = wrbuf_alloc();
+ WRBUF wrbuf = result;
if (!oid_oidcmp(input_format, yaz_oid_recsyn_sutrs))
{
- wrbuf_printf(wrbuf, ZINT_FORMAT, sysno);
+ wrbuf_printf(wrbuf, ZINT_FORMAT, fi->sysno);
*output_format = input_format;
}
else if (!oid_oidcmp(input_format, yaz_oid_recsyn_xml))
{
wrbuf_printf(wrbuf, ZEBRA_XML_HEADER_STR
" sysno=\"" ZINT_FORMAT "\"/>\n",
- sysno);
+ fi->sysno);
*output_format = input_format;
}
- *rec_lenp = wrbuf_len(wrbuf);
- if (*rec_lenp)
- *rec_bufp = odr_strdup(odr, wrbuf_cstr(wrbuf));
- else
+ if (wrbuf_len(wrbuf) == 0)
ret = YAZ_BIB1_NO_SYNTAXES_AVAILABLE_FOR_THIS_REQUEST;
- wrbuf_destroy(wrbuf);
return ret;
}
/* processing special elementsetname zebra::index:: for sort elements */
if (elemsetname && 0 == strncmp(elemsetname, "index", 5))
{
- int ret = zebra_special_sort_fetch(zh, sysno, odr,
- elemsetname + 5,
- input_format, output_format,
- rec_bufp, rec_lenp);
+ int ret = zebra_special_sort_fetch(
+ fi, elemsetname + 5,
+ input_format, output_format,
+ result, addinfo);
if (ret != -1)
return ret;
/* not a sort index so we continue to get the full record */
{
struct ZebraRecStream stream;
RecordAttr *recordAttr = rec_init_attr(zh->reg->zei, rec);
+ char *b;
+
zebra_create_record_stream(zh, &rec, &stream);
*output_format = input_format;
- *rec_lenp = recordAttr->recordSize;
- *rec_bufp = (char *) odr_malloc(odr, *rec_lenp);
- stream.readf(&stream, *rec_bufp, *rec_lenp);
+
+ b = nmem_malloc(fi->nmem, recordAttr->recordSize);
+ stream.readf(&stream, b, recordAttr->recordSize);
+ wrbuf_write(result, b, recordAttr->recordSize);
+
stream.destroy(&stream);
rec_free(&rec);
return 0;
return YAZ_BIB1_NO_SYNTAXES_AVAILABLE_FOR_THIS_REQUEST;
}
-
/* processing special elementsetnames zebra::meta:: */
if (elemsetname && 0 == strcmp(elemsetname, "meta"))
{
int ret = 0;
- WRBUF wrbuf = wrbuf_alloc();
+ WRBUF wrbuf = result;
RecordAttr *recordAttr = rec_init_attr(zh->reg->zei, rec);
if (!oid_oidcmp(input_format, yaz_oid_recsyn_xml))
retrieve_puts_attr(wrbuf, "base", rec->info[recInfo_databaseName]);
retrieve_puts_attr(wrbuf, "file", rec->info[recInfo_filename]);
retrieve_puts_attr(wrbuf, "type", rec->info[recInfo_fileType]);
- if (score >= 0)
- retrieve_puts_attr_int(wrbuf, "score", score);
+ if (fi->score >= 0)
+ retrieve_puts_attr_int(wrbuf, "score", fi->score);
wrbuf_printf(wrbuf,
" rank=\"" ZINT_FORMAT "\""
retrieve_puts_str(wrbuf, "base", rec->info[recInfo_databaseName]);
retrieve_puts_str(wrbuf, "file", rec->info[recInfo_filename]);
retrieve_puts_str(wrbuf, "type", rec->info[recInfo_fileType]);
- if (score >= 0)
- retrieve_puts_int(wrbuf, "score", score);
+ if (fi->score >= 0)
+ retrieve_puts_int(wrbuf, "score", fi->score);
wrbuf_printf(wrbuf,
"rank " ZINT_FORMAT "\n"
recordAttr->recordSize,
elemsetname);
}
- *rec_lenp = wrbuf_len(wrbuf);
- if (*rec_lenp)
- *rec_bufp = odr_strdup(odr, wrbuf_cstr(wrbuf));
- else
+ if (wrbuf_len(wrbuf) == 0)
ret = YAZ_BIB1_SYSTEM_ERROR_IN_PRESENTING_RECORDS;
- wrbuf_destroy(wrbuf);
rec_free(&rec);
return ret;
}
/* processing special elementsetnames zebra::index:: */
if (elemsetname && 0 == strncmp(elemsetname, "index", 5))
{
- int ret = zebra_special_index_fetch(zh, sysno, odr, rec,
- elemsetname + 5,
- input_format, output_format,
- rec_bufp, rec_lenp);
-
+ int ret = zebra_special_index_fetch(
+ fi, elemsetname + 5,
+ input_format, output_format,
+ result, addinfo, rec);
rec_free(&rec);
return ret;
}
return YAZ_BIB1_SPECIFIED_ELEMENT_SET_NAME_NOT_VALID_FOR_SPECIFIED_;
}
-
int zebra_record_fetch(ZebraHandle zh, const char *setname,
zint sysno, int score,
ODR odr,
zint sysnos[MAX_SYSNOS_PER_RECORD];
int no_sysnos = MAX_SYSNOS_PER_RECORD;
ZEBRA_RES res;
+ struct special_fetch_s fetch_info;
res = zebra_result_recid_to_sysno(zh, setname, sysno, sysnos, &no_sysnos);
if (res != ZEBRA_OK)
*addinfo = 0;
elemsetname = yaz_get_esn(comp);
+ fetch_info.zh = zh;
+ fetch_info.setname = setname;
+ fetch_info.sysno = sysno;
+ fetch_info.score = score;
+ fetch_info.nmem = odr->mem;
+
/* processing zebra special elementset names of form 'zebra:: */
if (elemsetname && 0 == strncmp(elemsetname, "zebra::", 7))
- return zebra_special_fetch(zh, setname, sysno, score, odr,
- elemsetname + 7,
+ {
+ WRBUF result = wrbuf_alloc();
+ WRBUF addinfo_w = wrbuf_alloc();
+ int r = zebra_special_fetch(&fetch_info, elemsetname + 7,
input_format, output_format,
- rec_bufp, rec_lenp);
-
+ result, addinfo_w);
+ if (r == 0)
+ {
+ *rec_bufp = odr_strdup(odr, wrbuf_cstr(result));
+ *rec_lenp = wrbuf_len(result);
+ }
+ else
+ {
+ if (wrbuf_len(addinfo_w))
+ *addinfo = odr_strdup(odr, wrbuf_cstr(addinfo_w));
+ }
+ wrbuf_destroy(result);
+ wrbuf_destroy(addinfo_w);
+ return r;
+ }
/* processing all other element set names */
rec = rec_get(zh->reg->records, sysno);
retrieveCtrl.res = zh->res;
retrieveCtrl.rec_buf = 0;
retrieveCtrl.rec_len = -1;
+ retrieveCtrl.handle = &fetch_info;
+ retrieveCtrl.special_fetch = zebra_special_fetch;
if (!(rt = recType_byName(zh->reg->recTypes, zh->res,
file_type, &clientData)))
dom-index-pi.xsl \
dom-index-skipped.xsl \
dom-config-del.xml \
+ dom-brief.xsl \
+ dom-snippet.xsl \
del-col.xml \
id.xsl \
index.xsl \
--- /dev/null
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:m="http://www.loc.gov/MARC21/slim"
+ xmlns:z="http://indexdata.com/zebra-2.0"
+ exclude-result-prefixes="m z"
+ version="1.0">
+ <xsl:output indent="yes" method="xml" version="1.0" encoding="UTF-8"/>
+
+ <xsl:template match="text()"/>
+
+ <xsl:template match="m:datafield[@tag='245']">
+ <title>
+ <xsl:value-of select="m:subfield[@code='a']"/>
+ </title>
+ </xsl:template>
+
+</xsl:stylesheet>
<retrieve name="F">
<xslt stylesheet="id.xsl"/>
</retrieve>
+ <retrieve name="B">
+ <xslt stylesheet="dom-brief.xsl"/>
+ </retrieve>
+ <retrieve name="snippet">
+ <xslt stylesheet="dom-snippet.xsl"/>
+ <meta/>
+ </retrieve>
<input syntax="xml">
<xmlreader level="1"/>
</input>
--- /dev/null
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:m="http://www.loc.gov/MARC21/slim"
+ xmlns:z="http://indexdata.com/zebra-2.0"
+ exclude-result-prefixes="m z"
+ version="1.0">
+ <xsl:output indent="yes" method="xml" version="1.0" encoding="UTF-8"/>
+
+ <xsl:template match="text()"/>
+
+ <xsl:template match="/">
+ <root>
+ <z:meta element_set_name="snippet"/>
+ <xsl:apply-templates/>
+ </root>
+ </xsl:template>
+ <xsl:template match="m:datafield[@tag='245']">
+ <title>
+ <xsl:value-of select="m:subfield[@code='a']"/>
+ </title>
+ </xsl:template>
+
+</xsl:stylesheet>
/* testing XMLREADER input with PI stylesheet */
zh = index_some(zs, "dom.dom-config-col.xml", "marc-col.xml");
YAZ_CHECK(tl_query(zh, "@attr 1=title computer", 3));
+
+ /* fetch first using dom-brief.xsl */
+ YAZ_CHECK_EQ(tl_fetch_first_compare(
+ zh, "B", yaz_oid_recsyn_xml,
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<title>How to program a computer</title>\n"),
+ ZEBRA_OK);
+ /* fetch first using dom-snippets.xsl */
+ YAZ_CHECK_EQ(tl_fetch_first_compare(
+ zh, "snippet", yaz_oid_recsyn_xml,
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<root>\n"
+ " <z:meta xmlns:z=\"http://indexdata.com/zebra-2.0\" element_set_name=\"snippet\">"
+ "<record xmlns=\"http://www.indexdata.com/zebra/\">\n"
+ " <snippet name=\"title\" type=\"w\">How to program a <s>computer</s></snippet>\n"
+ "</record></z:meta>\n"
+ " <title>How to program a computer</title>\n"
+ "</root>\n"),
+ ZEBRA_OK);
+
YAZ_CHECK(tl_query(zh, "@attr 1=control 11224466", 1));
+
YAZ_CHECK(tl_query_x(zh, "@attr 1=titl computer", 0, 114));
YAZ_CHECK(tl_query_x(zh, "@attr 1=4 computer", 0, 121));
zebra_close(zh);
+
/* testing XMLREADER input with ELEMENT stylesheet */
zh = index_some(zs, "dom.dom-config-one.xml", "marc-one.xml");
YAZ_CHECK(tl_query(zh, "@attr 1=title computer", 1));