28#include <yaz/diagbib1.h>
30#include <yaz/oid_db.h>
31#include <yaz/snprintf.h>
33#include <libxml/xmlversion.h>
34#include <libxml/parser.h>
35#include <libxml/tree.h>
36#include <libxml/xmlIO.h>
37#include <libxml/xmlreader.h>
38#include <libxslt/transform.h>
39#include <libxslt/xsltutils.h>
42#include <libexslt/exslt.h>
70#define ZEBRA_SCHEMA_XSLT_NS "http://indexdata.dk/zebra/xslt/1"
72#define XML_STRCMP(a,b) strcmp((char*)a, b)
73#define XML_STRLEN(a) strlen((char*)a)
78 const char *value, ODR odr)
80 char *quoted = odr_malloc(odr, 3 + strlen(value));
81 yaz_snprintf(quoted, 3 + strlen(value),
"'" ZINT_FORMAT "'", value);
92 char *quoted = odr_malloc(odr, 30);
93 yaz_snprintf(quoted, 30,
"'" ZINT_FORMAT "'", value);
101#define ENABLE_INPUT_CALLBACK 0
103#if ENABLE_INPUT_CALLBACK
104static int zebra_xmlInputMatchCallback (
char const *filename)
106 yaz_log(YLOG_LOG,
"match %s", filename);
110static void * zebra_xmlInputOpenCallback (
char const *filename)
115static int zebra_xmlInputReadCallback (
void * context,
char * buffer,
int len)
120static int zebra_xmlInputCloseCallback (
void * context)
135 tinfo->
odr = odr_createmem(ODR_ENCODE);
143#if ENABLE_INPUT_CALLBACK
144 xmlRegisterDefaultInputCallbacks();
145 xmlRegisterInputCallbacks(zebra_xmlInputMatchCallback,
146 zebra_xmlInputOpenCallback,
147 zebra_xmlInputReadCallback,
148 zebra_xmlInputCloseCallback);
154 const char **dst_content)
156 if (!
XML_STRCMP(attr->name, name) && attr->children
157 && attr->children->type == XML_TEXT_NODE)
159 *dst_content = (
const char *)(attr->children->content);
174 schema = schema_next;
179 xmlFreeDoc(tinfo->
doc);
185 char tmp_full_name[1024];
187 tinfo->
fname = xstrdup(fname);
190 NULL, tmp_full_name))
191 tinfo->
full_name = xstrdup(tmp_full_name);
195 yaz_log(YLOG_LOG,
"alvis filter: loading config file %s", tinfo->
full_name);
201 yaz_log(YLOG_WARN,
"alvis filter: could not parse config file %s",
207 ptr = xmlDocGetRootElement(tinfo->
doc);
208 if (!ptr || ptr->type != XML_ELEMENT_NODE
212 "alvis filter: config file %s :"
213 " expected root element <schemaInfo>",
218 for (ptr = ptr->children; ptr; ptr = ptr->next)
220 if (ptr->type != XML_ELEMENT_NODE)
224 struct _xmlAttr *attr;
233 for (attr = ptr->properties; attr; attr = attr->next)
247 char tmp_xslt_full_name[1024];
249 NULL, tmp_xslt_full_name))
252 "alvis filter: stylesheet %s not found in path %s",
257 = xsltParseStylesheetFile((
const xmlChar*) tmp_xslt_full_name);
261 "alvis filter: could not parse xslt stylesheet %s",
269 struct _xmlAttr *attr;
270 for (attr = ptr->properties; attr; attr = attr->next)
272 const char *split_level_str = 0;
275 split_level_str ? atoi(split_level_str) : 0;
280 yaz_log(YLOG_WARN,
"Bad element %s in %s", ptr->name, fname);
292 for (schema = tinfo->
schemas; schema; schema = schema->
next)
300 if (schema->
name && !strcmp(schema->
name, est))
320 yaz_log(YLOG_WARN,
"alvis filter: need config file");
324 if (tinfo->
fname && !strcmp(args, tinfo->
fname))
328 yaz_log(YLOG_LOG,
"alvis filter: profilePath %s", tinfo->
profile_path);
340 xmlFreeTextReader(tinfo->
reader);
341 odr_destroy(tinfo->
odr);
345static int ioread_ex(
void *context,
char *buffer,
int len)
357 xmlNodePtr ptr,
RecWord *recWord)
359 for(; ptr; ptr = ptr->next)
362 if (ptr->type != XML_TEXT_NODE)
364 recWord->
term_buf = (
const char *)ptr->content;
371 xmlNodePtr ptr,
RecWord *recWord)
373 for(; ptr; ptr = ptr->next)
375 index_node(tinfo, ctrl, ptr->children, recWord);
376 if (ptr->type != XML_ELEMENT_NODE || !ptr->ns ||
381 const char *name_str = 0;
382 const char *type_str = 0;
383 const char *xpath_str = 0;
384 struct _xmlAttr *attr;
385 for (attr = ptr->properties; attr; attr = attr->next)
395 if (type_str && *type_str)
396 recWord->
index_type = (
const char *) type_str;
407 xmlNodePtr ptr,
RecWord *recWord)
409 const char *type_str =
"update";
411 if (ptr && ptr->type == XML_ELEMENT_NODE && ptr->ns &&
415 const char *id_str = 0;
416 const char *rank_str = 0;
417 struct _xmlAttr *attr;
418 for (attr = ptr->properties; attr; attr = attr->next)
432 if (!strcmp(
"update", type_str))
434 else if (!strcmp(
"delete", type_str))
435 yaz_log(YLOG_WARN,
"alvis filter delete: to be implemented");
437 yaz_log(YLOG_WARN,
"alvis filter: unknown record type '%s'",
445 const char *params[10];
454 (*p->
init)(p, &recWord);
464 xmlDocDumpMemory(resDoc, &buf_out, &len_out);
465 fwrite(buf_out, len_out, 1, stdout);
468 root_ptr = xmlDocGetRootElement(resDoc);
473 yaz_log(YLOG_WARN,
"No root for index XML record."
474 " split_level=%d stylesheet=%s",
479 xmlDocDumpMemory(doc, &buf_out, &len_out);
481 fwrite(buf_out, len_out, 1, stdout);
497 xmlFreeTextReader(tinfo->
reader);
509 ret = xmlTextReaderRead(tinfo->
reader);
512 int type = xmlTextReaderNodeType(tinfo->
reader);
513 int depth = xmlTextReaderDepth(tinfo->
reader);
514 if (type == XML_READER_TYPE_ELEMENT && tinfo->
split_level == depth)
516 xmlNodePtr ptr = xmlTextReaderExpand(tinfo->
reader);
519 xmlNodePtr ptr2 = xmlCopyNode(ptr, 1);
520 xmlDocPtr doc = xmlNewDoc((
const xmlChar*)
"1.0");
522 xmlDocSetRootElement(doc, ptr2);
528 xmlFreeTextReader(tinfo->
reader);
533 ret = xmlTextReaderRead(tinfo->
reader);
535 xmlFreeTextReader(tinfo->
reader);
568 odr_reset(tinfo->
odr);
590 const char *params[32];
598 if (p->
comp->which == Z_RecordComp_simple
599 && p->
comp->u.simple->which == Z_ElementSetNames_generic)
601 esn = p->
comp->u.simple->u.generic;
603 else if (p->
comp->which == Z_RecordComp_complex
604 && p->
comp->u.complex->generic->elementSpec
605 && p->
comp->u.complex->generic->elementSpec->which ==
606 Z_ElementSpec_elementSetName)
608 esn = p->
comp->u.complex->generic->elementSpec->u.elementSetName;
615 YAZ_BIB1_SPECIFIED_ELEMENT_SET_NAME_NOT_VALID_FOR_SPECIFIED_;
643 XML_PARSE_XINCLUDE | XML_PARSE_NOENT | XML_PARSE_NONET);
646 p->
diagnostic = YAZ_BIB1_SYSTEM_ERROR_IN_PRESENTING_RECORDS;
660 p->
diagnostic = YAZ_BIB1_SYSTEM_ERROR_IN_PRESENTING_RECORDS;
669 xsltSaveResultToString(&buf_out, &len_out, resDoc,
672 xmlDocDumpMemory(resDoc, &buf_out, &len_out);
680 else if (!oid_oidcmp(p->
output_format, yaz_oid_recsyn_sutrs))
686 xsltSaveResultToString(&buf_out, &len_out, resDoc,
689 xmlDocDumpMemory(resDoc, &buf_out, &len_out);
700 p->
diagnostic = YAZ_BIB1_RECORD_SYNTAX_UNSUPP;
717#if IDZEBRA_STATIC_ALVIS
static void index_cdata(struct filter_info *tinfo, struct recExtractCtrl *ctrl, xmlNodePtr ptr, RecWord *recWord)
static void filter_destroy(void *clientData)
#define ZEBRA_SCHEMA_XSLT_NS
static void * filter_init(Res res, RecType recType)
static struct filter_schema * lookup_schema(struct filter_info *tinfo, const char *est)
static ZEBRA_RES create_schemas(struct filter_info *tinfo, const char *fname)
static int ioclose_ret(void *context)
static struct recType filter_type
static int ioclose_ex(void *context)
static void set_param_int(const char **params, const char *name, zint value, ODR odr)
static int ioread_ret(void *context, char *buffer, int len)
static int attr_content(struct _xmlAttr *attr, const char *name, const char **dst_content)
static void index_record(struct filter_info *tinfo, struct recExtractCtrl *ctrl, xmlNodePtr ptr, RecWord *recWord)
static void set_param_str(const char **params, const char *name, const char *value, ODR odr)
static int extract_doc(struct filter_info *tinfo, struct recExtractCtrl *p, xmlDocPtr doc)
static void index_node(struct filter_info *tinfo, struct recExtractCtrl *ctrl, xmlNodePtr ptr, RecWord *recWord)
static int ioread_ex(void *context, char *buffer, int len)
static void destroy_schemas(struct filter_info *tinfo)
static int extract_full(struct filter_info *tinfo, struct recExtractCtrl *p)
static int extract_split(struct filter_info *tinfo, struct recExtractCtrl *p)
static const char * zebra_xslt_ns
static ZEBRA_RES filter_config(void *clientData, Res res, const char *args)
#define RECCTRL_EXTRACT_EOF
#define RECCTRL_EXTRACT_ERROR_GENERIC
#define RECCTRL_EXTRACT_OK
const char * res_get(Res r, const char *name)
int(* readf)(struct ZebraRecStream *s, char *buf, size_t count)
read function
struct filter_schema * schemas
const char * profile_path
xsltStylesheetPtr stylesheet_xsp
const char * default_schema
struct filter_schema * next
const Odr_oid * input_format
Z_RecordComposition * comp
struct ZebraRecStream * stream
const Odr_oid * output_format
zint atozint(const char *src)
short ZEBRA_RES
Common return type for Zebra API.