+ "info:lc/xmlns/marcxchange-v1",
+ 0, 0, 0);
+}
+
+#if YAZ_HAVE_XML2
+
+void add_marc_datafield_turbo_xml(yaz_marc_t mt, struct yaz_marc_node *n,
+ xmlNode *record_ptr,
+ xmlNsPtr ns_record, WRBUF wr_cdata,
+ int identifier_length)
+{
+ xmlNode *ptr;
+ struct yaz_marc_subfield *s;
+ WRBUF subfield_name = wrbuf_alloc();
+
+ /* TODO consider if safe */
+ char field[10];
+ field[0] = 'd';
+ strncpy(field + 1, n->u.datafield.tag, 3);
+ field[4] = '\0';
+ ptr = xmlNewChild(record_ptr, ns_record, BAD_CAST field, 0);
+
+ if (n->u.datafield.indicator)
+ {
+ int i;
+ for (i = 0; n->u.datafield.indicator[i]; i++)
+ {
+ char ind_str[6];
+ char ind_val[2];
+
+ ind_val[0] = n->u.datafield.indicator[i];
+ ind_val[1] = '\0';
+ sprintf(ind_str, "%s%d", indicator_name[1], i+1);
+ xmlNewProp(ptr, BAD_CAST ind_str, BAD_CAST ind_val);
+ }
+ }
+ for (s = n->u.datafield.subfields; s; s = s->next)
+ {
+ int not_written;
+ xmlNode *ptr_subfield;
+ size_t using_code_len = get_subfield_len(mt, s->code_data,
+ identifier_length);
+ wrbuf_rewind(wr_cdata);
+ wrbuf_iconv_puts(wr_cdata, mt->iconv_cd, s->code_data + using_code_len);
+ marc_iconv_reset(mt, wr_cdata);
+
+ wrbuf_rewind(subfield_name);
+ wrbuf_puts(subfield_name, "s");
+ not_written = element_name_append_attribute_value(mt, subfield_name, 0, s->code_data, using_code_len) != 0;
+ ptr_subfield = xmlNewTextChild(ptr, ns_record,
+ BAD_CAST wrbuf_cstr(subfield_name),
+ BAD_CAST wrbuf_cstr(wr_cdata));
+ if (not_written)
+ {
+ /* Generate code attribute value and add */
+ wrbuf_rewind(wr_cdata);
+ wrbuf_iconv_write(wr_cdata, mt->iconv_cd,s->code_data, using_code_len);
+ xmlNewProp(ptr_subfield, BAD_CAST "code", BAD_CAST wrbuf_cstr(wr_cdata));
+ }
+ }
+ wrbuf_destroy(subfield_name);
+}
+
+static int yaz_marc_write_xml_turbo_xml(yaz_marc_t mt, xmlNode **root_ptr,
+ const char *ns,
+ const char *format,
+ const char *type)
+{
+ struct yaz_marc_node *n;
+ int identifier_length;
+ const char *leader = 0;
+ xmlNode *record_ptr;
+ xmlNsPtr ns_record;
+ WRBUF wr_cdata = 0;
+
+ for (n = mt->nodes; n; n = n->next)
+ if (n->which == YAZ_MARC_LEADER)
+ {
+ leader = n->u.leader;
+ break;
+ }
+
+ if (!leader)
+ return -1;
+ if (!atoi_n_check(leader+11, 1, &identifier_length))
+ return -1;
+
+ wr_cdata = wrbuf_alloc();
+
+ record_ptr = xmlNewNode(0, BAD_CAST "r");
+ *root_ptr = record_ptr;
+
+ ns_record = xmlNewNs(record_ptr, BAD_CAST ns, 0);
+ xmlSetNs(record_ptr, ns_record);
+
+ if (format)
+ xmlNewProp(record_ptr, BAD_CAST "format", BAD_CAST format);
+ if (type)
+ xmlNewProp(record_ptr, BAD_CAST "type", BAD_CAST type);
+ for (n = mt->nodes; n; n = n->next)
+ {
+ xmlNode *ptr;
+
+ char field[10];
+ field[0] = 'c';
+ field[4] = '\0';
+
+ switch(n->which)
+ {
+ case YAZ_MARC_DATAFIELD:
+ add_marc_datafield_turbo_xml(mt, n, record_ptr, ns_record, wr_cdata, identifier_length);
+ break;
+ case YAZ_MARC_CONTROLFIELD:
+ wrbuf_rewind(wr_cdata);
+ wrbuf_iconv_puts(wr_cdata, mt->iconv_cd, n->u.controlfield.data);
+ marc_iconv_reset(mt, wr_cdata);
+
+ strncpy(field + 1, n->u.controlfield.tag, 3);
+ ptr = xmlNewTextChild(record_ptr, ns_record,
+ BAD_CAST field,
+ BAD_CAST wrbuf_cstr(wr_cdata));
+ break;
+ case YAZ_MARC_COMMENT:
+ ptr = xmlNewComment(BAD_CAST n->u.comment);
+ xmlAddChild(record_ptr, ptr);
+ break;
+ case YAZ_MARC_LEADER:
+ {
+ char *field = "leader";
+ field = "l";
+ xmlNewTextChild(record_ptr, ns_record, BAD_CAST field,
+ BAD_CAST n->u.leader);
+ }
+ break;
+ }
+ }
+ wrbuf_destroy(wr_cdata);
+ return 0;