<varlistentry><term>mergekey</term>
<listitem>
<para>
- If set to <literal>yes</literal>, the value of this
- metadata element is appended to the resulting mergekey.
- By default metadata is not part of a mergekey.
+ If set to '<literal>required</literal>', the value of this
+ metadata element is appended to the resulting mergekey if
+ the metadata is present in a record instance.
+ If the metadata element is not present, the a unique mergekey
+ will be generated instead.
+ </para>
+ <para>
+ If set to '<literal>optional</literal>', the value of this
+ metadata element is appended to the resulting mergekey if the
+ the metadata is present in a record instance. If the metadata
+ is not present, it will be empty.
+ </para>
+ <para>
+ If set to '<literal>no</literal>' or the mergekey attribute is
+ omitted, the metadata will not be used in the creation of a
+ mergekey.
</para>
</listitem>
</varlistentry>
return rec_md;
}
+static int get_mergekey_from_doc(xmlDoc *doc, xmlNode *root, const char *name,
+ struct conf_service *service, WRBUF norm_wr)
+{
+ xmlNode *n;
+ int no_found = 0;
+ for (n = root->children; n; n = n->next)
+ {
+ if (n->type != XML_ELEMENT_NODE)
+ continue;
+ if (!strcmp((const char *) n->name, "metadata"))
+ {
+ xmlChar *type = xmlGetProp(n, (xmlChar *) "type");
+ if (!strcmp(name, (const char *) type))
+ {
+ xmlChar *value = xmlNodeListGetString(doc, n->children, 1);
+ if (value)
+ {
+ const char *norm_str;
+ pp2_relevance_token_t prt =
+ pp2_relevance_tokenize(
+ service->mergekey_pct,
+ (const char *) value);
+
+ wrbuf_puts(norm_wr, name);
+ wrbuf_puts(norm_wr, "=");
+ while ((norm_str =
+ pp2_relevance_token_next(prt)))
+ {
+ if (*norm_str)
+ {
+ if (wrbuf_len(norm_wr))
+ wrbuf_puts(norm_wr, " ");
+ wrbuf_puts(norm_wr, norm_str);
+ }
+ }
+ xmlFree(value);
+ pp2_relevance_token_destroy(prt);
+ no_found++;
+ }
+ }
+ xmlFree(type);
+ }
+ }
+ return no_found;
+}
+
static const char *get_mergekey(xmlDoc *doc, struct client *cl, int record_no,
struct conf_service *service, NMEM nmem)
{
char *mergekey_norm = 0;
xmlNode *root = xmlDocGetRootElement(doc);
WRBUF norm_wr = wrbuf_alloc();
- xmlNode *n;
/* consider mergekey from XSL first */
xmlChar *mergekey = xmlGetProp(root, (xmlChar *) "mergekey");
else
{
/* no mergekey defined in XSL. Look for mergekey metadata instead */
- for (n = root->children; n; n = n->next)
+ int field_id;
+ for (field_id = 0; field_id < service->num_metadata; field_id++)
{
- if (n->type != XML_ELEMENT_NODE)
- continue;
- if (!strcmp((const char *) n->name, "metadata"))
+ struct conf_metadata *ser_md = &service->metadata[field_id];
+ if (ser_md->mergekey != Metadata_mergekey_no)
{
- struct conf_metadata *ser_md = 0;
- int md_field_id = -1;
-
- xmlChar *type = xmlGetProp(n, (xmlChar *) "type");
-
- if (!type)
- continue;
-
- md_field_id
- = conf_service_metadata_field_id(service,
- (const char *) type);
- if (md_field_id >= 0)
+ int r = get_mergekey_from_doc(doc, root, ser_md->name,
+ service, norm_wr);
+ if (r == 0 && ser_md->mergekey == Metadata_mergekey_required)
{
- ser_md = &service->metadata[md_field_id];
- if (ser_md->mergekey == Metadata_mergekey_yes)
- {
- xmlChar *value = xmlNodeListGetString(doc, n->children, 1);
- if (value)
- {
- const char *norm_str;
- pp2_relevance_token_t prt =
- pp2_relevance_tokenize(
- service->mergekey_pct,
- (const char *) value);
-
- while ((norm_str = pp2_relevance_token_next(prt)))
- {
- if (*norm_str)
- {
- if (wrbuf_len(norm_wr))
- wrbuf_puts(norm_wr, " ");
- wrbuf_puts(norm_wr, norm_str);
- }
- }
- xmlFree(value);
- pp2_relevance_token_destroy(prt);
- }
- }
+ /* no mergekey on this one and it is required..
+ Generate unique key instead */
+ wrbuf_rewind(norm_wr);
+ break;
}
- xmlFree(type);
}
}
}
else
sortkey_offset = -1;
- if (xml_mergekey && strcmp((const char *) xml_mergekey, "no"))
+ if (xml_mergekey)
{
- mergekey_type = Metadata_mergekey_yes;
+ if (!strcmp((const char *) xml_mergekey, "required"))
+ mergekey_type = Metadata_mergekey_required;
+ else if (!strcmp((const char *) xml_mergekey, "optional"))
+ mergekey_type = Metadata_mergekey_optional;
+ else if (!strcmp((const char *) xml_mergekey, "no"))
+ mergekey_type = Metadata_mergekey_no;
+ else
+ {
+ yaz_log(YLOG_FATAL, "Unknown value for mergekey: %s", xml_mergekey);
+ return -1;
+ }
}
xmlFree(xml_termlist);
xmlFree(xml_rank);
xmlFree(xml_setting);
+ xmlFree(xml_mergekey);
(*md_node)++;
return 0;
}