X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=recctrl%2Frecgrs.c;h=4f3ab503291a0f8b2cc28eaf8575a532663acbc4;hb=83574dcb462d530758e21aea0a8a843cd0dce60f;hp=58ad1bbfae10eee9d2c6947b696b885e00670a52;hpb=a4abda703eec54c664657d7ad581a47cd2f198a2;p=idzebra-moved-to-github.git diff --git a/recctrl/recgrs.c b/recctrl/recgrs.c index 58ad1bb..4f3ab50 100644 --- a/recctrl/recgrs.c +++ b/recctrl/recgrs.c @@ -1,4 +1,4 @@ -/* $Id: recgrs.c,v 1.65 2002-08-30 12:44:31 adam Exp $ +/* $Id: recgrs.c,v 1.71 2002-12-16 20:27:18 adam Exp $ Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002 Index Data Aps @@ -102,6 +102,9 @@ static void *grs_init(RecType recType) #if HAVE_EXPAT_H grs_add_handler (h, recTypeGrs_xml); #endif +#if HAVE_PERL + grs_add_handler (h, recTypeGrs_perl); +#endif return h; } @@ -120,6 +123,62 @@ static void grs_destroy(void *clientData) xfree (h); } +/* *ostrich* + + New function, looking for xpath "element" definitions in abs, by + tagpath, using a kind of ugly regxp search.The DFA was built while + parsing abs, so here we just go trough them and try to match + against the given tagpath. The first matching entry is returned. + + pop, 2002-12-13 + */ + +data1_termlist *xpath_termlist_by_tagpath(char *tagpath, data1_node *n) +{ + data1_absyn *abs = n->root->u.root.absyn; + data1_xpelement *xpe = abs->xp_elements; + char *pexpr = malloc(strlen(tagpath)+2); + int ok = 0; + + sprintf (pexpr, "%s\n", tagpath); + while (xpe) + { + struct DFA_state **dfaar = xpe->dfa->states; + struct DFA_state *s=dfaar[0]; + struct DFA_tran *t; + const char *p; + int i; + unsigned char c; + int start_line = 1; + + c = *pexpr++; t = s->trans; i = s->tran_no; + if (c >= t->ch[0] && c <= t->ch[1]) { + p = pexpr; + do { + if ((s = dfaar[t->to])->rule_no && + (start_line || s->rule_nno)) { + ok = 1; + break; + } + for (t=s->trans, i=s->tran_no; --i >= 0; t++) { + if ((unsigned) *p >= t->ch[0] && (unsigned) *p <= t->ch[1]) + break; + } + p++; + } while (i >= 0); + } + pexpr--; + if (ok) break; + xpe = xpe->next; + } + + if (ok) { + return xpe->termlists; + } else { + return NULL; + } +} + /* use 1 start element (tag) 2 end element @@ -128,6 +187,14 @@ static void grs_destroy(void *clientData) 1016 cdata 1015 attr data + + *ostrich* + + Now, if there is a matching xelm described in abs, for the + indexed element or the attribute, then the data is handled according + to those definitions... + + modified by pop, 2002-12-13 */ static void index_xpath (data1_node *n, struct recExtractCtrl *p, @@ -141,24 +208,64 @@ static void index_xpath (data1_node *n, struct recExtractCtrl *p, switch (n->which) { case DATA1N_data: - wrd->reg_type = 'w'; wrd->string = n->u.data.data; wrd->length = n->u.data.len; - wrd->attrSet = VAL_IDXPATH, - wrd->attrUse = use; if (p->flagShowRecords) { printf("%*s data=", (level + 1) * 4, ""); for (i = 0; ilength && i < 8; i++) fputc (wrd->string[i], stdout); printf("\n"); - } - else - { - (*p->tokenAdd)(wrd); + } + else { + data1_termlist *tl; + int xpdone = 0; + flen = 0; + + /* we have to fetch the whole path to the data tag */ + for (nn = n; nn; nn = nn->parent) { + if (nn->which == DATA1N_tag) { + size_t tlen = strlen(nn->u.tag.tag); + if (tlen + flen > (sizeof(tag_path_full)-2)) return; + memcpy (tag_path_full + flen, nn->u.tag.tag, tlen); + flen += tlen; + tag_path_full[flen++] = '/'; + } + else if (nn->which == DATA1N_root) break; + } + + tag_path_full[flen] = 0; + + /* If we have a matching termlist... */ + if (tl = xpath_termlist_by_tagpath(tag_path_full, n)) { + for (; tl; tl = tl->next) { + wrd->reg_type = *tl->structure; + /* this is the ! case, so structure is for the xpath index */ + if (!tl->att) { + wrd->attrSet = VAL_IDXPATH; + wrd->attrUse = use; + (*p->tokenAdd)(wrd); + xpdone = 1; + /* this is just the old fashioned attribute based index */ + } else { + wrd->attrSet = (int) (tl->att->parent->reference); + wrd->attrUse = tl->att->locals->local; + (*p->tokenAdd)(wrd); + } + } + } + /* xpath indexing is done, if there was no termlist given, + or no ! attribute... */ + if (!xpdone) { + wrd->attrSet = VAL_IDXPATH; + wrd->attrUse = use; + wrd->reg_type = 'w'; + (*p->tokenAdd)(wrd); + } } break; case DATA1N_tag: + flen = 0; for (nn = n; nn; nn = nn->parent) { if (nn->which == DATA1N_tag) @@ -173,6 +280,8 @@ static void index_xpath (data1_node *n, struct recExtractCtrl *p, else if (nn->which == DATA1N_root) break; } + + wrd->reg_type = '0'; wrd->string = tag_path_full; wrd->length = flen; @@ -229,7 +338,6 @@ static void index_xpath (data1_node *n, struct recExtractCtrl *p, sprintf (attr_tag_path_full, "@%s/%.*s", xp->name, int_len, tag_path_full); - wrd->reg_type = '0'; wrd->attrUse = 1; wrd->string = attr_tag_path_full; @@ -238,13 +346,40 @@ static void index_xpath (data1_node *n, struct recExtractCtrl *p, if (xp->value) { - wrd->attrUse = 1015; - wrd->reg_type = 'w'; + /* the same jokes, as with the data nodes ... */ + data1_termlist *tl; + int xpdone = 0; + wrd->string = xp->value; wrd->length = strlen(xp->value); - (*p->tokenAdd)(wrd); + wrd->reg_type = 'w'; + + if (tl = xpath_termlist_by_tagpath(attr_tag_path_full, + n)) { + for (; tl; tl = tl->next) { + wrd->reg_type = *tl->structure; + if (!tl->att) { + wrd->attrSet = VAL_IDXPATH; + wrd->attrUse = 1015; + (*p->tokenAdd)(wrd); + xpdone = 1; + } else { + wrd->attrSet = (int) (tl->att->parent->reference); + wrd->attrUse = tl->att->locals->local; + (*p->tokenAdd)(wrd); + } + } + + } + if (!xpdone) { + wrd->attrSet = VAL_IDXPATH; + wrd->attrUse = 1015; + wrd->reg_type = 'w'; + (*p->tokenAdd)(wrd); + } } + wrd->attrSet = VAL_IDXPATH; wrd->reg_type = '0'; wrd->attrUse = 2; wrd->string = attr_tag_path_full; @@ -261,6 +396,7 @@ static void index_termlist (data1_node *par, data1_node *n, { data1_termlist *tlist = 0; data1_datatype dtype = DATA1K_string; + /* * cycle up towards the root until we find a tag with an att.. * this has the effect of indexing locally defined tags with @@ -268,19 +404,20 @@ static void index_termlist (data1_node *par, data1_node *n, */ while (!par->u.tag.element) - if (!par->parent || !(par=get_parent_tag(p->dh, par->parent))) - break; + if (!par->parent || !(par=get_parent_tag(p->dh, par->parent))) + break; if (!par || !(tlist = par->u.tag.element->termlists)) - return; + return; if (par->u.tag.element->tag) - dtype = par->u.tag.element->tag->kind; + dtype = par->u.tag.element->tag->kind; for (; tlist; tlist = tlist->next) { + char xattr[512]; /* consider source */ wrd->string = 0; - + if (!strcmp (tlist->source, "data") && n->which == DATA1N_data) { wrd->string = n->u.data.data; @@ -592,46 +729,52 @@ static int process_comp(data1_handle dh, data1_node *n, Z_RecordComposition *c) } } -static void add_nice_whitespace (struct recRetrieveCtrl *p, data1_node *top, - NMEM mem) -{ - data1_node *n = top->child; - while (n && n->which == DATA1N_data && n->u.data.what == DATA1I_text) - { - data1_mk_text_n(p->dh, mem, n->u.data.data, n->u.data.len, top); - n = n->next; - } -} +/* Add Zebra info in separate namespace ... + + 359 + 447 + records/genera.xml + + +*/ -static void add_idzebra_info (struct recRetrieveCtrl *p, data1_node *top, - NMEM mem) +static void zebra_xml_metadata (struct recRetrieveCtrl *p, data1_node *top, + NMEM mem) { - const char *idzebra_ns[7]; + const char *idzebra_ns[3]; + const char *i2 = "\n "; + const char *i4 = "\n "; + data1_node *n; - idzebra_ns[0] = "xmlns:idzebra"; + idzebra_ns[0] = "xmlns"; idzebra_ns[1] = "http://www.indexdata.dk/zebra/"; idzebra_ns[2] = 0; - data1_tag_add_attr (p->dh, mem, top, idzebra_ns); + data1_mk_text (p->dh, mem, i2, top); + + n = data1_mk_tag (p->dh, mem, "idzebra", idzebra_ns, top); + + data1_mk_text (p->dh, mem, "\n", top); + + data1_mk_text (p->dh, mem, i4, n); + + data1_mk_tag_data_int (p->dh, n, "size", p->recordSize, mem); - add_nice_whitespace (p, top, mem); - data1_mk_tag_data_int (p->dh, top, "idzebra:size", p->recordSize, - mem); if (p->score != -1) { - add_nice_whitespace (p, top, mem); - data1_mk_tag_data_int (p->dh, top, "idzebra:score", - p->score, mem); + data1_mk_text (p->dh, mem, i4, n); + data1_mk_tag_data_int (p->dh, n, "score", p->score, mem); } - add_nice_whitespace (p, top, mem); - data1_mk_tag_data_int (p->dh, top, "idzebra:localnumber", p->localno, - mem); + data1_mk_text (p->dh, mem, i4, n); + data1_mk_tag_data_int (p->dh, n, "localnumber", p->localno, mem); if (p->fname) { - add_nice_whitespace (p, top, mem); - data1_mk_tag_data_text(p->dh, top, "idzebra:filename", - p->fname, mem); + data1_mk_text (p->dh, mem, i4, n); + data1_mk_tag_data_text(p->dh, n, "filename", p->fname, mem); } + data1_mk_text (p->dh, mem, i2, n); } static int grs_retrieve(void *clientData, struct recRetrieveCtrl *p) @@ -642,7 +785,7 @@ static int grs_retrieve(void *clientData, struct recRetrieveCtrl *p) int res, selected = 0; NMEM mem; struct grs_read_info gri; - char *tagname; + const char *tagname; struct grs_handlers *h = (struct grs_handlers *) clientData; int requested_schema = VAL_NONE; data1_marctab *marctab; @@ -680,16 +823,18 @@ static int grs_retrieve(void *clientData, struct recRetrieveCtrl *p) top = data1_get_root_tag (p->dh, node); logf (LOG_DEBUG, "grs_retrieve: size"); - if ((dnew = data1_mk_tag_data_wd(p->dh, top, "size", mem))) + tagname = data1_systag_lookup(node->u.root.absyn, "size", "size"); + if (tagname && + (dnew = data1_mk_tag_data_wd(p->dh, top, tagname, mem))) { dnew->u.data.what = DATA1I_text; dnew->u.data.data = dnew->lbuf; sprintf(dnew->u.data.data, "%d", p->recordSize); dnew->u.data.len = strlen(dnew->u.data.data); } - - tagname = res_get_def(p->res, "tagrank", "rank"); - if (strcmp(tagname, "0") && p->score >= 0 && + + tagname = data1_systag_lookup(node->u.root.absyn, "rank", "rank"); + if (tagname && p->score >= 0 && (dnew = data1_mk_tag_data_wd(p->dh, top, tagname, mem))) { logf (LOG_DEBUG, "grs_retrieve: %s", tagname); @@ -699,14 +844,15 @@ static int grs_retrieve(void *clientData, struct recRetrieveCtrl *p) dnew->u.data.len = strlen(dnew->u.data.data); } - tagname = res_get_def(p->res, "tagsysno", "localControlNumber"); - if (strcmp(tagname, "0") && p->localno > 0 && - (dnew = data1_mk_tag_data_wd(p->dh, top, tagname, mem))) + tagname = data1_systag_lookup(node->u.root.absyn, "sysno", + "localControlNumber"); + if (tagname && p->localno > 0 && + (dnew = data1_mk_tag_data_wd(p->dh, top, tagname, mem))) { logf (LOG_DEBUG, "grs_retrieve: %s", tagname); dnew->u.data.what = DATA1I_text; dnew->u.data.data = dnew->lbuf; - + sprintf(dnew->u.data.data, "%d", p->localno); dnew->u.data.len = strlen(dnew->u.data.data); } @@ -798,9 +944,7 @@ static int grs_retrieve(void *clientData, struct recRetrieveCtrl *p) sprintf(p, "%d", *ii); p += strlen(p); } - *(p++) = '\0'; - - if ((dnew = data1_mk_tag_data_wd(dh, node, + if ((dnew = data1_mk_tag_data_wd(dh, top, "schemaIdentifier", mem))) { dnew->u.data.what = DATA1I_oid; @@ -824,7 +968,7 @@ static int grs_retrieve(void *clientData, struct recRetrieveCtrl *p) else if (p->comp && !res) selected = 1; -#if 1 +#if 0 data1_pr_tree (p->dh, node, stdout); #endif logf (LOG_DEBUG, "grs_retrieve: transfer syntax mapping"); @@ -832,7 +976,11 @@ static int grs_retrieve(void *clientData, struct recRetrieveCtrl *p) p->input_format : VAL_SUTRS)) { case VAL_TEXT_XML: - add_idzebra_info (p, top, mem); + zebra_xml_metadata (p, top, mem); + +#if 0 + data1_pr_tree (p->dh, node, stdout); +#endif if (p->encoding) data1_iconv (p->dh, mem, node, p->encoding, "UTF-8");