+#if HAVE_XSLT
+int Yaz_ProxyConfig::check_schema(xmlNodePtr ptr, Z_RecordComposition *comp,
+ const char *schema_identifier)
+{
+ char *esn = 0;
+ int default_match = 1;
+ if (comp && comp->which == Z_RecordComp_simple &&
+ comp->u.simple && comp->u.simple->which == Z_ElementSetNames_generic)
+ {
+ esn = comp->u.simple->u.generic;
+ }
+ // if no ESN/schema was given accept..
+ if (!esn)
+ return 1;
+ // check if schema identifier match
+ if (schema_identifier && !strcmp(esn, schema_identifier))
+ return 1;
+ // Check each name element
+ for (; ptr; ptr = ptr->next)
+ {
+ if (ptr->type == XML_ELEMENT_NODE
+ && !strcmp((const char *) ptr->name, "name"))
+ {
+ xmlNodePtr tptr = ptr->children;
+ default_match = 0;
+ for (; tptr; tptr = tptr->next)
+ if (tptr->type == XML_TEXT_NODE && tptr->content)
+ {
+ xmlChar *t = tptr->content;
+ while (*t && isspace(*t))
+ t++;
+ int i = 0;
+ while (esn[i] && esn[i] == t[i])
+ i++;
+ if (!esn[i] && (!t[i] || isspace(t[i])))
+ return 1;
+ }
+ }
+ }
+ return default_match;
+}
+#endif
+
+int Yaz_ProxyConfig::check_syntax(ODR odr, const char *name,
+ Odr_oid *syntax, Z_RecordComposition *comp,
+ char **addinfo,
+ char **stylesheet, char **schema)
+{
+ if (stylesheet)
+ {
+ xfree (*stylesheet);
+ *stylesheet = 0;
+ }
+ if (schema)
+ {
+ xfree (*schema);
+ *schema = 0;
+ }
+#if HAVE_XSLT
+ int syntax_has_matched = 0;
+ xmlNodePtr ptr;
+
+ ptr = find_target_node(name, 0);
+ if (!ptr)
+ return 0;
+ for(ptr = ptr->children; ptr; ptr = ptr->next)
+ {
+ if (ptr->type == XML_ELEMENT_NODE &&
+ !strcmp((const char *) ptr->name, "syntax"))
+ {
+ int match = 0; // if we match record syntax
+ const char *match_type = 0;
+ const char *match_error = 0;
+ const char *match_marcxml = 0;
+ const char *match_stylesheet = 0;
+ const char *match_identifier = 0;
+ struct _xmlAttr *attr;
+ for (attr = ptr->properties; attr; attr = attr->next)
+ {
+ if (!strcmp((const char *) attr->name, "type") &&
+ attr->children && attr->children->type == XML_TEXT_NODE)
+ match_type = (const char *) attr->children->content;
+ if (!strcmp((const char *) attr->name, "error") &&
+ attr->children && attr->children->type == XML_TEXT_NODE)
+ match_error = (const char *) attr->children->content;
+ if (!strcmp((const char *) attr->name, "marcxml") &&
+ attr->children && attr->children->type == XML_TEXT_NODE)
+ match_marcxml = (const char *) attr->children->content;
+ if (!strcmp((const char *) attr->name, "stylesheet") &&
+ attr->children && attr->children->type == XML_TEXT_NODE)
+ match_stylesheet = (const char *) attr->children->content;
+ if (!strcmp((const char *) attr->name, "identifier") &&
+ attr->children && attr->children->type == XML_TEXT_NODE)
+ match_identifier = (const char *) attr->children->content;
+ }
+ if (match_type)
+ {
+ if (!strcmp(match_type, "*"))
+ match = 1;
+ else if (!strcmp(match_type, "none"))
+ {
+ if (syntax == 0)
+ match = 1;
+ }
+ else if (syntax)
+ {
+ int match_oid[OID_SIZE];
+ oid_name_to_oid(CLASS_RECSYN, match_type, match_oid);
+ if (oid_oidcmp(match_oid, syntax) == 0)
+ match = 1;
+ }
+ }
+ if (match)
+ {
+ if (!match_error)
+ syntax_has_matched = 1;
+ match = check_schema(ptr->children, comp, match_identifier);
+ }
+ if (match)
+ {
+ if (stylesheet && match_stylesheet)
+ {
+ xfree(*stylesheet);
+ *stylesheet = xstrdup(match_stylesheet);
+ }
+ if (schema && match_identifier)
+ {
+ xfree(*schema);
+ *schema = xstrdup(match_identifier);
+ }
+ if (match_marcxml)
+ {
+ return -1;
+ }
+ if (match_error)
+ {
+ if (syntax_has_matched) // if syntax OK, bad schema/ESN
+ return 25;
+ if (syntax)
+ {
+ char dotoid_str[100];
+ oid_to_dotstring(syntax, dotoid_str);
+ *addinfo = odr_strdup(odr, dotoid_str);
+ }
+ return atoi(match_error);
+ }
+ return 0;
+ }
+ }
+ }
+#endif
+ return 0;
+}
+
+#if HAVE_XSLT
+xmlNodePtr Yaz_ProxyConfig::find_target_db(xmlNodePtr ptr, const char *db)
+{
+ xmlNodePtr dptr;
+ if (!db)
+ return ptr;
+ if (!ptr)
+ return 0;
+ for (dptr = ptr->children; dptr; dptr = dptr->next)
+ if (dptr->type == XML_ELEMENT_NODE &&
+ !strcmp((const char *) dptr->name, "database"))
+ {
+ struct _xmlAttr *attr;
+ for (attr = dptr->properties; attr; attr = attr->next)
+ if (!strcmp((const char *) attr->name, "name"))
+ {
+ if (attr->children
+ && attr->children->type==XML_TEXT_NODE
+ && attr->children->content
+ && (!strcmp((const char *) attr->children->content, db)
+ || !strcmp((const char *) attr->children->content,
+ "*")))
+ return dptr;
+ }
+ }
+ return ptr;
+}
+
+xmlNodePtr Yaz_ProxyConfig::find_target_node(const char *name, const char *db)