From: Adam Dickmeiss Date: Thu, 5 Dec 2013 15:40:55 +0000 (+0100) Subject: JSON / MARC encoding X-Git-Tag: v5.0.5~16 X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=commitdiff_plain;h=bbfac2e92dee794029b7a2ee6c843c9b99e22cc3 JSON / MARC encoding --- diff --git a/include/yaz/json.h b/include/yaz/json.h index aab0159..d3974ae 100644 --- a/include/yaz/json.h +++ b/include/yaz/json.h @@ -201,6 +201,14 @@ void json_write_wrbuf_pretty(struct json_node *node, WRBUF result); YAZ_EXPORT void wrbuf_json_puts(WRBUF b, const char *str); +/** \brief writes JSON text to WRBUF with escaping + \param b result + \param cp char buffer + \param sz size of char buffer +*/ +YAZ_EXPORT +void wrbuf_json_write(WRBUF b, const char *cp, size_t sz); + YAZ_END_CDECL #endif diff --git a/include/yaz/marcdisp.h b/include/yaz/marcdisp.h index f1eaae8..0b2b66b 100644 --- a/include/yaz/marcdisp.h +++ b/include/yaz/marcdisp.h @@ -76,6 +76,8 @@ YAZ_EXPORT void yaz_marc_xml(yaz_marc_t mt, int xmlmode); #define YAZ_MARC_CHECK 6 /** \brief Output format: Turbo MARC Index Data format (XML based) */ #define YAZ_MARC_TURBOMARC 7 +/** \brief Output format: JSON */ +#define YAZ_MARC_JSON 8 /** \brief set iconv handle for character set conversion */ YAZ_EXPORT void yaz_marc_iconv(yaz_marc_t mt, yaz_iconv_t cd); diff --git a/src/json.c b/src/json.c index 1933b8a..2364e43 100644 --- a/src/json.c +++ b/src/json.c @@ -462,7 +462,7 @@ struct json_node *json_parse(const char *json_str, const char **errmsg) return json_parse2(json_str, errmsg, 0); } -static void wrbuf_json_write(WRBUF b, const char *cp, size_t sz) +void wrbuf_json_write(WRBUF b, const char *cp, size_t sz) { size_t i; for (i = 0; i < sz; i++) diff --git a/src/marcdisp.c b/src/marcdisp.c index ad9eed6..78244a0 100644 --- a/src/marcdisp.c +++ b/src/marcdisp.c @@ -632,6 +632,8 @@ int yaz_marc_write_mode(yaz_marc_t mt, WRBUF wr) return yaz_marc_write_iso2709(mt, wr); case YAZ_MARC_CHECK: return yaz_marc_write_check(mt, wr); + case YAZ_MARC_JSON: + return yaz_marc_write_json(mt, wr); } return -1; } @@ -1238,6 +1240,87 @@ int yaz_marc_write_iso2709(yaz_marc_t mt, WRBUF wr) return 0; } +int yaz_marc_write_json(yaz_marc_t mt, WRBUF w) +{ + int identifier_length; + struct yaz_marc_node *n; + const char *leader = 0; + int first = 1; + + wrbuf_puts(w, "{\n"); + for (n = mt->nodes; n; n = n->next) + if (n->which == YAZ_MARC_LEADER) + leader = n->u.leader; + + if (!leader) + return -1; + + if (!atoi_n_check(leader+11, 1, &identifier_length)) + return -1; + + wrbuf_puts(w, "\t\"leader\":\""); + wrbuf_json_puts(w, leader); + wrbuf_puts(w, "\",\n"); + wrbuf_puts(w, "\t\"fields\":\n\t[\n"); + + for (n = mt->nodes; n; n = n->next) + { + struct yaz_marc_subfield *s; + int i; + const char *sep = ""; + switch (n->which) + { + case YAZ_MARC_CONTROLFIELD: + if (first) + first = 0; + else + wrbuf_puts(w, ",\n"); + wrbuf_puts(w, "\t\t{\n\t\t\t\""); + wrbuf_json_puts(w, n->u.controlfield.tag); + wrbuf_puts(w, "\":\""); + wrbuf_json_puts(w, n->u.controlfield.data); + wrbuf_puts(w, "\"\n\t\t}"); + break; + case YAZ_MARC_DATAFIELD: + if (first) + first = 0; + else + wrbuf_puts(w, ",\n"); + + wrbuf_puts(w, "\t\t{\n\t\t\t\""); + wrbuf_json_puts(w, n->u.datafield.tag); + wrbuf_puts(w, "\":\n\t\t\t{\n\t\t\t\t\"subfields\":\n\t\t\t\t[\n"); + for (s = n->u.datafield.subfields; s; s = s->next) + { + size_t using_code_len = get_subfield_len(mt, s->code_data, + identifier_length); + wrbuf_puts(w, sep); + sep = ",\n"; + wrbuf_puts(w, "\t\t\t\t\t{\n\t\t\t\t\t\t\""); + wrbuf_json_write(w, s->code_data, using_code_len); + wrbuf_puts(w, "\":\""); + wrbuf_json_puts(w, s->code_data + using_code_len); + wrbuf_puts(w, "\"\n\t\t\t\t\t}"); + } + wrbuf_puts(w, "\n\t\t\t\t]"); + if (n->u.datafield.indicator[0]) + { + int i; + for (i = 0; n->u.datafield.indicator[i]; i++) + { + wrbuf_puts(w, ",\n"); + wrbuf_printf(w, "\t\t\t\t\"ind%d\":\"%c\"", i + 1, + n->u.datafield.indicator[i]); + } + } + wrbuf_puts(w, "\n\t\t\t}\n"); + wrbuf_puts(w, "\n\t\t}"); + break; + } + } + wrbuf_puts(w, "\n\t]\n"); + wrbuf_puts(w, "}\n"); +} int yaz_marc_decode_wrbuf(yaz_marc_t mt, const char *buf, int bsize, WRBUF wr) { @@ -1368,6 +1451,8 @@ int yaz_marc_decode_formatstr(const char *arg) mode = YAZ_MARC_XCHANGE; if (!strcmp(arg, "line")) mode = YAZ_MARC_LINE; + if (!strcmp(arg, "json")) + mode = YAZ_MARC_JSON; return mode; }