OpenRefine au service de BACON : quelle évaluation pour les fichiers KBART ? [3] – Cas pratique

[Lire le billet qui introduit cette série « OpenRefine au service de BACON : quelle évaluation pour les fichiers KBART ? »]

Dans le cadre de l’accompagnement des éditeurs scientifiques francophones à la mise en œuvre de la recommandation KBART, les fichiers sont évalués par l’Abes à l’aide d’OpenRefine.

Les tests menés sont de différents types : syntaxiques et sémantiques. Les premiers vérifient la conformité du format des métadonnées au regard des règles édictées par la recommandation. Les seconds comparent les informations contenues dans le fichier à celles du SUDOC.

Un script GREL a été réalisé, pour l’évaluation des périodiques d’une part, des livres électroniques d’autre part.

La dernière version du script utilisé pour l’évaluation des périodiques est la suivante :

[ { "op": "core/text-transform", "description": "Script syntaxique : pour chaque ligne, test l'ensemble des champs. Si une ligne ne contient que des champs vides, alors la mention « ligne vide » apparaît dans le champ publication_title de la ligne concernée", "engineConfig": { "mode": "row-based", "facets": [] }, "columnName": "publication_title", "expression": "grel:if(cells.publication_title.value.length()==0,(if(cells.print_identifier.value.length()==0,(if(cells .online_identifier.value.length()==0,(if(cells.date_first_issue_online.value.length()==0,(if(cells.num_first_vol_online.value.length()==0,(if(cells.num_first_issue_online.value.length()==0,(if(cells.date_last_issue_online.value.length()==0,(if(cells.num_last_vol_online.value.length()==0,(if(cells.num_last_issue_online.value.length()==0,(if(cells.title_url.value.length()==0,(if(cells .first_author.value.length()==0,(if(cells.title_id.value.length()==0,(if(cells.embargo_info.value.length()==0,(if(cells.coverage_depth.value.length()==0,(if(cells.notes.value.length()==0,(if(cells.publisher_name.value.length()==0,(if(cells.publication_type.value.length()==0,(if(cells.date_monograph_published_print.value.length()==0,(if(cells.date_monograph_published_online.value.length()==0,(if(cells.monograph_volume.value.length()==0,(if(cells.monograph_edition.value.length()==0,(if(cells.first_editor.value.length()==0,(if(cells.parent_publication_title_id.value.length()==0,(if(cells.preceding_publication_title_id.value.length()==0,(if(cells.access_type.value.length()==0,'ligne vide',value)),value)),value)),value)),value)),value)),value)),value)),value)),value)),value)),value)),value)),value)),value)),value)),value)),value)),value)),value)),value)),value)),value)),value)),value)", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Suppression des espaces en début et en fin de cellule", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "publication_title", "expression": "value.trim()", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Suppression des espaces en début et en fin de cellule", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "print_identifier", "expression": "value.trim()", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Suppression des espaces en début et en fin de cellule", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "online_identifier", "expression": "value.trim()", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Suppression des espaces en début et en fin de cellule", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "date_first_issue_online", "expression": "value.trim()", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Suppression des espaces en début et en fin de cellule", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "num_first_vol_online", "expression": "value.trim()", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Suppression des espaces en début et en fin de cellule", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "num_first_issue_online", "expression": "value.trim()", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Suppression des espaces en début et en fin de cellule", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "date_last_issue_online", "expression": "value.trim()", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Suppression des espaces en début et en fin de cellule", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "num_last_vol_online", "expression": "value.trim()", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Suppression des espaces en début et en fin de cellule", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "num_last_issue_online", "expression": "value.trim()", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Suppression des espaces en début et en fin de cellule", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "title_url", "expression": "value.trim()", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Suppression des espaces en début et en fin de cellule", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "title_id", "expression": "value.trim()", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Suppression des espaces en début et en fin de cellule", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "embargo_info", "expression": "value.trim()", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Suppression des espaces en début et en fin de cellule", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "coverage_depth", "expression": "value.trim()", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Suppression des espaces en début et en fin de cellule", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "publisher_name", "expression": "value.trim()", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Suppression des espaces en début et en fin de cellule", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "publication_type", "expression": "value.trim()", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Suppression des espaces en début et en fin de cellule", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "preceding_publication_title_id", "expression": "value.trim()", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Suppression des espaces en début et en fin de cellule", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "access_type", "expression": "value.trim()", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Si plusieurs caractères d’espaces consécutifs, fusion en un seul", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "publication_title", "expression": "value.replace(/\\s+/,' ')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Si plusieurs caractères d’espaces consécutifs, fusion en un seul", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "print_identifier", "expression": "value.replace(/\\s+/,' ')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Si plusieurs caractères d’espaces consécutifs, fusion en un seul", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "online_identifier", "expression": "value.replace(/\\s+/,' ')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Si plusieurs caractères d’espaces consécutifs, fusion en un seul", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "date_first_issue_online", "expression": "value.replace(/\\s+/,' ')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Si plusieurs caractères d’espaces consécutifs, fusion en un seul", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "num_first_vol_online", "expression": "value.replace(/\\s+/,' ')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Si plusieurs caractères d’espaces consécutifs, fusion en un seul", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "num_first_issue_online", "expression": "value.replace(/\\s+/,' ')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Si plusieurs caractères d’espaces consécutifs, fusion en un seul", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "date_last_issue_online", "expression": "value.replace(/\\s+/,' ')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Si plusieurs caractères d’espaces consécutifs, fusion en un seul", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "num_last_vol_online", "expression": "value.replace(/\\s+/,' ')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Si plusieurs caractères d’espaces consécutifs, fusion en un seul", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "num_last_issue_online", "expression": "value.replace(/\\s+/,' ')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Si plusieurs caractères d’espaces consécutifs, fusion en un seul", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "title_url", "expression": "value.replace(/\\s+/,' ')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Si plusieurs caractères d’espaces consécutifs, fusion en un seul", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "title_id", "expression": "value.replace(/\\s+/,' ')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Si plusieurs caractères d’espaces consécutifs, fusion en un seul", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "embargo_info", "expression": "value.replace(/\\s+/,' ')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Si plusieurs caractères d’espaces consécutifs, fusion en un seul", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "coverage_depth", "expression": "value.replace(/\\s+/,' ')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Si plusieurs caractères d’espaces consécutifs, fusion en un seul", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "notes", "expression": "value.replace(/\\s+/,' ')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Si plusieurs caractères d’espaces consécutifs, fusion en un seul", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "publisher_name", "expression": "value.replace(/\\s+/,' ')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Si plusieurs caractères d’espaces consécutifs, fusion en un seul", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "publication_type", "expression": "value.replace(/\\s+/,' ')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Si plusieurs caractères d’espaces consécutifs, fusion en un seul", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "preceding_publication_title_id", "expression": "value.replace(/\\s+/,' ')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Si plusieurs caractères d’espaces consécutifs, fusion en un seul", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "access-type", "expression": "value.replace(/\\s+/,' ')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : suppression du caractère de retour à la ligne et du caractère d'espace insécable", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "publication_title", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : suppression du caractère de retour à la ligne et du caractère d'espace insécable", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "print_identifier", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : suppression du caractère de retour à la ligne et du caractère d'espace insécable", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "online_identifier", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : suppression du caractère de retour à la ligne et du caractère d'espace insécable", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "date_first_issue_online", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : suppression du caractère de retour à la ligne et du caractère d'espace insécable", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "num_first_vol_online", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : suppression du caractère de retour à la ligne et du caractère d'espace insécable", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "num_first_issue_online", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : suppression du caractère de retour à la ligne et du caractère d'espace insécable", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "date_last_issue_online", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : suppression du caractère de retour à la ligne et du caractère d'espace insécable", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "num_last_vol_online", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : suppression du caractère de retour à la ligne et du caractère d'espace insécable", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "num_last_issue_online", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : suppression du caractère de retour à la ligne et du caractère d'espace insécable", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "title_url", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : suppression du caractère de retour à la ligne et du caractère d'espace insécable", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "title_id", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : suppression du caractère de retour à la ligne et du caractère d'espace insécable", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "embargo_info", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : suppression du caractère de retour à la ligne et du caractère d'espace insécable", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "coverage_depth", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "SScript syntaxique : suppression du caractère de retour à la ligne et du caractère d'espace insécable", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "notes", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : suppression du caractère de retour à la ligne et du caractère d'espace insécable", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "publisher_name", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : suppression du caractère de retour à la ligne et du caractère d'espace insécable", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "publication_type", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : suppression du caractère de retour à la ligne et du caractère d'espace insécable", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "preceding_publication_title_id", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : suppression du caractère de retour à la ligne et du caractère d'espace insécable", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "access_type", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : remplace le x minuscule par un X majuscule pour les p-ISSN", "engineConfig": { "mode": "row-based", "facets": [] }, "columnName": "print_identifier", "expression": "grel:value.replace(\"x\",\"X\")", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : remplace le x minuscule par un X majuscule pour les e-ISSN", "engineConfig": { "mode": "row-based", "facets": [] }, "columnName": "online_identifier", "expression": "grel:value.replace(\"x\",\"X\")", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/column-addition", "description": "Script syntaxique : doublons sur le publication_title", "engineConfig": { "mode": "row-based", "facets": [] }, "newColumnName": "publication_title_doublon", "columnInsertIndex": 25, "baseColumnName": "publication_title", "expression": "grel:forNonBlank(value,v,facetCount(v,'value','publication_title'),'')", "onError": "set-to-blank" }, { "op": "core/text-transform", "description": "Script syntaxique : vérifie qu'aucun champ du publication_title n'est vide", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "publication_title", "expression": "grel:if(isBlank(value)==true,'titre manquant',value)", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/column-addition", "description": "Script syntaxique : doublons sur le print_identifier", "engineConfig": { "mode": "row-based", "facets": [] }, "newColumnName": "print_identifier_doublon", "columnInsertIndex": 26, "baseColumnName": "print_identifier", "expression": "grel:forNonBlank(value,v,facetCount(v,'value','print_identifier'),'')", "onError": "set-to-blank" }, { "op": "core/column-addition", "description": "Script syntaxique : doublons sur le online_identifier", "engineConfig": { "mode": "row-based", "facets": [] }, "newColumnName": "online_identifier_doublon", "columnInsertIndex": 27, "baseColumnName": "online_identifier", "expression": "grel:forNonBlank(value,v,facetCount(v,'value','online_identifier'),'')", "onError": "set-to-blank" }, { "op": "core/text-transform", "description": "Script syntaxique : ne conserve que les quatre premiers caractères contenus dans le date_first_issue_online, à condition qu'ils respectent le format YYYY. Sinon, renvoie un message d'erreur", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "date_first_issue_online", "expression": "grel:if(value.match(/.*(\\d{4}).*/)[0]==null,value+' : format incorrect',value.match(/.*(\\d{4}).*/)[0])", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : ne conserve que les quatre premiers caractères contenus dans le date_last_issue_online, à condition qu'ils respectent le format YYYY. Sinon, informe d'une erreur de format", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "date_last_issue_online", "expression": "grel:if(isNonBlank(value),if(value.match(/.*(\\d{4}).*/)[0]==null,value+' : format incorrect',value.match(/.*(\\d{4}).*/)[0]),value)", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/column-addition", "description": "Script syntaxique : le contenu du num_first_vol_online, lorsqu'il n'est pas numérique, suit-il une cohérence ?", "engineConfig": { "mode": "row-based", "facets": [] }, "newColumnName": "num_first_vol_non_numérique", "columnInsertIndex": 28, "baseColumnName": "num_first_vol_online", "expression": "grel:if(isNotNull(value.match(/[0-9]*/)),'','cohérent ? '+value)", "onError": "set-to-blank" }, { "op": "core/column-addition", "description": "Script syntaxique : le contenu du num_first_issue_online, lorsqu'il n'est pas numérique, suit-il une cohérence ?", "engineConfig": { "mode": "row-based", "facets": [] }, "newColumnName": "num_first_issue_non_numérique", "columnInsertIndex": 29, "baseColumnName": "num_first_issue_online", "expression": "grel:if(isNotNull(value.match(/[0-9]*/)),'','cohérent ? '+value)", "onError": "set-to-blank" }, { "op": "core/column-addition", "description": "Script syntaxique : le contenu du num_last_vol_online, lorsqu'il n'est pas numérique, suit-il une cohérence ?", "engineConfig": { "mode": "row-based", "facets": [] }, "newColumnName": "num_last_vol_non_numérique", "columnInsertIndex": 30, "baseColumnName": "num_last_vol_online", "expression": "grel:if(isNotNull(value.match(/[0-9]*/)),'','cohérent ? '+value)", "onError": "set-to-blank" }, { "op": "core/column-addition", "description": "Script syntaxique : le contenu du num_last_issue_online, lorsqu'il n'est pas numérique, suit-il une cohérence ?", "engineConfig": { "mode": "row-based", "facets": [] }, "newColumnName": "num_last_issue_non_numérique", "columnInsertIndex": 31, "baseColumnName": "num_last_issue_online", "expression": "grel:if(isNotNull(value.match(/[0-9]*/)),'','cohérent ? '+value)", "onError": "set-to-blank" }, { "op": "core/text-transform", "description": "Script syntaxique : URL manquante", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "title_url", "expression": "grel:if(isBlank(value)==true,'URL obligatoire',value)", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/column-addition", "description": "Script syntaxique : la partie fixe du title_url mise de côté, la partie évolutive restante correspond-elle au title_id ? Test I ATTENTION : A ACTUALISER AVANT D'UTILISER LE SCRIPT : remplacer [X] par la partie fixe de l'URL", "engineConfig": { "mode": "record-based", "facets": [] }, "newColumnName": "title_url_bis", "columnInsertIndex": 32, "baseColumnName": "title_url", "expression": "grel:value.replace('[X]','')", "onError": "set-to-blank" }, { "op": "core/column-addition", "description": "Script syntaxique : la partie fixe du title_url mise de côté, la partie évolutive restante correspond-elle au title_id ? Test II", "engineConfig": { "mode": "row-based", "facets": [] }, "newColumnName": "title_url_vs_title_id", "columnInsertIndex": 33, "baseColumnName": "title_url_bis", "expression": "grel:if(value==cells['title_id'].value,'','erreur ? '+value)", "onError": "set-to-blank" }, { "op": "core/text-transform", "description": "Script syntaxique : champ obligatoirement vide", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "first_author", "expression": "grel:if(isBlank(value)!=true,value+' : doit être vide','')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : champ obligatoirement vide", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "date_monograph_published_print", "expression": "grel:if(isBlank(value)!=true,value+' : doit être vide','')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : champ obligatoirement vide", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "date_monograph_published_online", "expression": "grel:if(isBlank(value)!=true,value+' : doit être vide','')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : champ obligatoirement vide", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "monograph_volume", "expression": "grel:if(isBlank(value)!=true,value+' : doit être vide','')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : champ obligatoirement vide", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "monograph_edition", "expression": "grel:if(isBlank(value)!=true,value+' : doit être vide','')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : champ obligatoirement vide", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "first_editor", "expression": "grel:if(isBlank(value)!=true,value+' : doit être vide','')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : champ obligatoirement vide", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "parent_publication_title_id", "expression": "grel:if(isBlank(value)!=true,value+' : doit être vide','')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : peut être vide ou contient strictement : P ou R + 1 à 9999 + Y ou M ou D", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "embargo_info", "expression": "grel:if(isBlank(value),value,if(isNotNull(value.match(/[PR]\\d{1,4}[YMD]/)),'',value+': format incorrect'))", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : contient obligatoirement « fulltext », « selected articles » ou abstract", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "coverage_depth", "expression": "grel:if(isNotNull(value.match(/fulltext|selected articles|abstracts/)),'',value+' : format incorrect')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : ne peut pas être vide", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "publisher_name", "expression": "grel:if(isBlank(value)!=false,'doit être renseigné',value)", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : contient obligatoirement « serial »", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "publication_type", "expression": "grel:if(isNotNull(value.match(/serial/)),value,value+' : format incorrect')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : contient obligatoirement P ou F", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "access_type", "expression": "grel:if(isNotNull(value.match(/[PF]/)),value,value+' : format incorrect')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/column-addition", "description": "Script sémantique : création d'une nouvelle colonne, qui récupère la valeur du date_first_issue_online et lui donne le format Number", "engineConfig": { "facets": [], "mode": "row-based" }, "newColumnName": "year_first_issue", "columnInsertIndex": 34, "baseColumnName": "date_first_issue_online", "expression": "grel:value.split(\"-\")[0].toNumber()", "onError": "set-to-blank" }, { "op": "core/column-addition", "description": "Script sémantique : création d'une nouvelle colonne, qui récupère la valeur du date_last_issue_online et lui donne le format Number", "engineConfig": { "facets": [], "mode": "row-based" }, "newColumnName": "last_year_issue", "columnInsertIndex": 35, "baseColumnName": "date_last_issue_online", "expression": "grel:value.split(\"-\")[0].toNumber()", "onError": "set-to-blank" }, { "op": "core/column-addition-by-fetching-urls", "description": "Script sémantique : indique quel webservice (issnbacon) interroger pour la récupération des informations de référence dans le SUDOC", "engineConfig": { "facets": [], "mode": "row-based" }, "newColumnName": "sudoc_print_identifier", "columnInsertIndex": 36, "baseColumnName": "print_identifier", "urlExpression": "grel:'https://bacon.abes.fr/issnbacon/'+value+'.json'", "onError": "set-to-blank", "delay": 10 }, { "op": "core/column-addition", "description": "Script sémantique : indiquer, le cas échéant, l'écart entre le type de média donné par le SUDOC et le type d'identifiant (en l'occurrence papier)", "engineConfig": { "facets": [], "mode": "row-based" }, "newColumnName": "erreur_print_media", "columnInsertIndex": 37, "baseColumnName": "sudoc_print_identifier", "expression": "grel:if(value!=null+isNonBlank(cells[\"print_identifier\"].value),(if(value.parseJson()[\"sudoc\"][\"ppn\"][\"media\"]!=\"a\",cells[\"print_identifier\"].value+\" n'est pas un imprime\",forEach(value.parseJson().sudoc,v,[v.ppn.media,v.ppn.content].join(':')).join(' '))),'')", "onError": "set-to-blank" }, { "op": "core/column-addition", "description": "Script sémantique : récupérer les informations associées au webservice issnbacon pour la date de début de couverture", "engineConfig": { "facets": [], "mode": "row-based" }, "newColumnName": "sudoc_startdate", "columnInsertIndex": 38, "baseColumnName": "sudoc_print_identifier", "expression": "grel:value.parseJson()[\"sudoc\"][\"ppn\"][\"startdate\"]", "onError": "set-to-blank" }, { "op": "core/column-addition", "description": "Script sémantique : renvoie le ppn de la notice si la date SUDOC est plus récente que la date de début de couverture, indice d'une métarevue non déployée", "engineConfig": { "facets": [], "mode": "row-based" }, "newColumnName": "erreur_print_date", "columnInsertIndex": 39, "baseColumnName": "year_first_issue", "expression": "grel:if(value<cells[\"sudoc_startdate\"].value, cells[\"sudoc_print_identifier\"].value.parseJson()[\"sudoc\"][\"ppn\"][\"content\"],\"\")", "onError": "set-to-blank" }, { "op": "core/column-addition", "description": "Script sémantique : si la colonne erreur_print_date contient un élément, rappel des dates : date SUDOC > date_first_issue_online", "engineConfig": { "facets": [], "mode": "row-based" }, "newColumnName": "date_sudoc>date_first", "columnInsertIndex": 40, "baseColumnName": "erreur_print_date", "expression": "grel:if(isBlank(value),'',cells[\"sudoc_print_identifier\"].value.parseJson()[\"sudoc\"][\"ppn\"][\"startdate\"]+' > '+cells[\"date_first_issue_online\"].value)", "onError": "set-to-blank" }, { "op": "core/column-addition-by-fetching-urls", "description": "Script sémantique : indique quel webservice (issnbacon) interroger pour la récupération des informations de référence dans le SUDOC, pour le online_identifier", "engineConfig": { "facets": [], "mode": "row-based" }, "newColumnName": "sudoc_online_identifier", "columnInsertIndex": 41, "baseColumnName": "online_identifier", "urlExpression": "grel:'https://bacon.abes.fr/issnbacon/'+value+'.json'", "onError": "set-to-blank", "delay": 10 }, { "op": "core/column-addition", "description": "Script sémantique : indiquer, le cas échéant, l'écart entre le type de média donné par le SUDOC et le type d'identifiant (en l'occurrence électronique)", "engineConfig": { "facets": [], "mode": "row-based" }, "newColumnName": "erreur_online_media", "columnInsertIndex": 42, "baseColumnName": "sudoc_online_identifier", "expression": "grel:if(value!=null+isNonBlank(cells[\"online_identifier\"].value),(if(value.parseJson()[\"sudoc\"][\"ppn\"][\"media\"]!=\"l\",cells[\"online_identifier\"].value+\" n'est pas un imprime\",forEach(value.parseJson().sudoc,v,[v.ppn.media,v.ppn.content].join(':')).join(' '))),'')", "onError": "set-to-blank" }, { "op": "core/column-removal", "description": "Script sémantique : supprime la colonne year_first_issue", "columnName": "year_first_issue" }, { "op": "core/column-removal", "description": "Script sémantique : supprime la colonne last_year_issue", "columnName": "last_year_issue" }, { "op": "core/column-removal", "description": "Script sémantique : supprime la colonne sudoc_startdate", "columnName": "sudoc_startdate" }, { "op": "core/text-transform", "description": "Script syntaxique : p-ISSN non conforme", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "print_identifier", "expression": "grel:forNonBlank(value,v,if(v.match(/^\\d{4}-\\d{3}(\\d|X)$/)!=null,value,value+\" n'est pas un ISSN conforme\"),'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : e-ISSN non conforme", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "online_identifier", "expression": "grel:forNonBlank(value,v,if(v.match(/^\\d{4}-\\d{3}(\\d|X)$/)!=null,value,value+\" n'est pas un ISSN conforme\"),'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : vérifie qu'un titre dispose au moins d'un ISSN", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "print_identifier", "expression": "grel:if(isBlank(value),(if(isBlank(cells[\"online_identifier\"].value),'aucun ISSN',value)),value)", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : aucun p-ISSN mais un e-ISSN : s'agit-il d'une revue numérique native ?", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "print_identifier", "expression": "grel:if(isBlank(value)==true,'revue numerique native ?',value)", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : tous les eISSN doivent être renseignés, y compris si la revue a été numérisée (demande à faire auprès du CIEPS)", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "online_identifier", "expression": "grel:if(isBlank(value)==true,'ISSN obligatoire',value)", "onError": "keep-original", "repeat": false, "repeatCount": 10 } ]

Celle pour l’évaluation des livres électroniques :

[ { "op": "core/text-transform", "description": "Script syntaxique : pour chaque ligne, test l'ensemble des champs. Si une ligne ne contient que des champs vides, alors la mention « ligne vide » apparaît dans le champ publication_title de la ligne concernée", "engineConfig": { "mode": "row-based", "facets": [] }, "columnName": "publication_title", "expression": "grel:if(cells.publication_title.value.length()==0,(if(cells.print_identifier.value.length()==0,(if(cells .online_identifier.value.length()==0,(if(cells.date_first_issue_online.value.length()==0,(if(cells.num_first_vol_online.value.length()==0,(if(cells.num_first_issue_online.value.length()==0,(if(cells.date_last_issue_online.value.length()==0,(if(cells.num_last_vol_online.value.length()==0,(if(cells.num_last_issue_online.value.length()==0,(if(cells.title_url.value.length()==0,(if(cells .first_author.value.length()==0,(if(cells.title_id.value.length()==0,(if(cells.embargo_info.value.length()==0,(if(cells.coverage_depth.value.length()==0,(if(cells.notes.value.length()==0,(if(cells.publisher_name.value.length()==0,(if(cells.publication_type.value.length()==0,(if(cells.date_monograph_published_print.value.length()==0,(if(cells.date_monograph_published_online.value.length()==0,(if(cells.monograph_volume.value.length()==0,(if(cells.monograph_edition.value.length()==0,(if(cells.first_editor.value.length()==0,(if(cells.parent_publication_title_id.value.length()==0,(if(cells.preceding_publication_title_id.value.length()==0,(if(cells.access_type.value.length()==0,'ligne vide',value)),value)),value)),value)),value)),value)),value)),value)),value)),value)),value)),value)),value)),value)),value)),value)),value)),value)),value)),value)),value)),value)),value)),value)),value)", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Suppression des espaces en début et en fin de cellule", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "publication_title", "expression": "value.trim()", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Suppression des espaces en début et en fin de cellule", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "print_identifier", "expression": "value.trim()", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Suppression des espaces en début et en fin de cellule", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "online_identifier", "expression": "value.trim()", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Suppression des espaces en début et en fin de cellule", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "title_url", "expression": "value.trim()", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Suppression des espaces en début et en fin de cellule", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "first_author", "expression": "value.trim()", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Suppression des espaces en début et en fin de cellule", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "title_id", "expression": "value.trim()", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Suppression des espaces en début et en fin de cellule", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "coverage_depth", "expression": "value.trim()", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Suppression des espaces en début et en fin de cellule", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "publisher_name", "expression": "value.trim()", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Suppression des espaces en début et en fin de cellule", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "publication_type", "expression": "value.trim()", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Suppression des espaces en début et en fin de cellule", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "date_monograph_published_print", "expression": "value.trim()", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Suppression des espaces en début et en fin de cellule", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "date_monograph_published_online", "expression": "value.trim()", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Suppression des espaces en début et en fin de cellule", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "monograph_volume", "expression": "value.trim()", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Suppression des espaces en début et en fin de cellule", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "monograph_edition", "expression": "value.trim()", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Suppression des espaces en début et en fin de cellule", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "first_editor", "expression": "value.trim()", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Suppression des espaces en début et en fin de cellule", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "parent_publication_title_id", "expression": "value.trim()", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Suppression des espaces en début et en fin de cellule", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "access_type", "expression": "value.trim()", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Si plusieurs caractères d’espaces consécutifs, fusion en un seul", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "publication_title", "expression": "value.replace(/\\s+/,' ')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Si plusieurs caractères d’espaces consécutifs, fusion en un seul", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "print_identifier", "expression": "value.replace(/\\s+/,' ')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Si plusieurs caractères d’espaces consécutifs, fusion en un seul", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "online_identifier", "expression": "value.replace(/\\s+/,' ')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Si plusieurs caractères d’espaces consécutifs, fusion en un seul", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "title_url", "expression": "value.replace(/\\s+/,' ')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Si plusieurs caractères d’espaces consécutifs, fusion en un seul", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "first_author", "expression": "value.replace(/\\s+/,' ')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Si plusieurs caractères d’espaces consécutifs, fusion en un seul", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "title_id", "expression": "value.replace(/\\s+/,' ')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Si plusieurs caractères d’espaces consécutifs, fusion en un seul", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "coverage_depth", "expression": "value.replace(/\\s+/,' ')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Si plusieurs caractères d’espaces consécutifs, fusion en un seul", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "publisher_name", "expression": "value.replace(/\\s+/,' ')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Si plusieurs caractères d’espaces consécutifs, fusion en un seul", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "publication_type", "expression": "value.replace(/\\s+/,' ')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Si plusieurs caractères d’espaces consécutifs, fusion en un seul", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "date_monograph_published_print", "expression": "value.replace(/\\s+/,' ')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Si plusieurs caractères d’espaces consécutifs, fusion en un seul", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "date_monograph_published_online", "expression": "value.replace(/\\s+/,' ')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Si plusieurs caractères d’espaces consécutifs, fusion en un seul", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "monograph_volume", "expression": "value.replace(/\\s+/,' ')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Si plusieurs caractères d’espaces consécutifs, fusion en un seul", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "monograph_edition", "expression": "value.replace(/\\s+/,' ')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Si plusieurs caractères d’espaces consécutifs, fusion en un seul", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "first_editor", "expression": "value.replace(/\\s+/,' ')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Si plusieurs caractères d’espaces consécutifs, fusion en un seul", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "parent_publication_title_id", "expression": "value.replace(/\\s+/,' ')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : Si plusieurs caractères d’espaces consécutifs, fusion en un seul", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "access_type", "expression": "value.replace(/\\s+/,' ')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : suppression du caractère de retour à la ligne", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "publication_title", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : suppression du caractère de retour à la ligne", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "print_identifier", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : suppression du caractère de retour à la ligne", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "online_identifier", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : suppression du caractère de retour à la ligne", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "title_url", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : suppression du caractère de retour à la ligne", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "first_author", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : suppression du caractère de retour à la ligne", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "title_id", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : suppression du caractère de retour à la ligne", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "coverage_depth", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : suppression du caractère de retour à la ligne", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "publisher_name", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : suppression du caractère de retour à la ligne", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "publication_type", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : suppression du caractère de retour à la ligne", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "date_monograph_published_print", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : suppression du caractère de retour à la ligne", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "date_monograph_published_online", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : suppression du caractère de retour à la ligne", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "monograph_volume", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : suppression du caractère de retour à la ligne", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "monograph_edition", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : suppression du caractère de retour à la ligne", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "first_editor", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : suppression du caractère de retour à la ligne", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "parent_publication_title_id", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "SScript syntaxique : suppression du caractère de retour à la ligne", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "access_type", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : suppression du caractère d'espace insécable", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "publication_title", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : suppression du caractère d'espace insécable", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "print_identifier", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : suppression du caractère d'espace insécable", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "online_identifier", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : suppression du caractère d'espace insécable", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "title_url", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : suppression du caractère d'espace insécable", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "first_author", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : suppression du caractère d'espace insécable", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "title_id", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : suppression du caractère d'espace insécable", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "coverage_depth", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : suppression du caractère d'espace insécable", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "publisher_name", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : suppression du caractère d'espace insécable", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "publication_type", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : suppression du caractère d'espace insécable", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "date_monograph_published_print", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : suppression du caractère d'espace insécable", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "date_monograph_published_online", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : suppression du caractère d'espace insécable", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "monograph_volume", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : suppression du caractère d'espace insécable", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "monograph_edition", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : suppression du caractère d'espace insécable", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "first_editor", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : suppression du caractère d'espace insécable", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "parent_publication_title_id", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : suppression du caractère d'espace insécable", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "access_type", "expression": "grel:value.replace(/\\u000a/,'').replace(/\\u00A0/,'')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/column-addition-by-fetching-urls", "description": "Script sémantique : création d'une colonne contenant les informations du Sudoc à partir du online_identifier grâce au webservice 'isbnbacon'", "engineConfig": { "mode": "row-based", "facets": [] }, "newColumnName": "E-ISBN_sudoc_json", "columnInsertIndex": 25, "baseColumnName": "online_identifier", "urlExpression": "grel:if(value!=null,'https://bacon.abes.fr/isbnbacon/'+value+'.json','')", "onError": "set-to-blank", "delay": 10 }, { "op": "core/column-addition", "description": "Script sémantique : création d'une colonne contenant le publication_title nettoyé", "engineConfig": { "facets": [], "mode": "row-based" }, "newColumnName": "pub_title_clean", "columnInsertIndex": 25, "baseColumnName": "publication_title", "expression": "grel:toLowercase(trim(value.replace(/\\u00A0/, ' '))).replace(/\\p{Punct}/,' ').replace(/\\u2019/, ' ').replace(/\\u200E/, ' ').replace(/\\s+/, ' ')", "onError": "set-to-blank" }, { "op": "core/text-transform", "description": "Script syntaxique : remplace le x minuscule par un X majuscule pour les p-ISBN", "engineConfig": { "mode": "row-based", "facets": [] }, "columnName": "print_identifier", "expression": "grel:value.replace(\"x\",\"X\")", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : remplace le x minuscule par un X majuscule pour les e-ISBN", "engineConfig": { "mode": "row-based", "facets": [] }, "columnName": "online_identifier", "expression": "grel:value.replace(\"x\",\"X\")", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/column-addition", "description": "Script sémantique : création d'une colonne contenant le titre sudoc", "engineConfig": { "facets": [], "mode": "row-based" }, "newColumnName": "E-sudoc_title", "columnInsertIndex": 25, "baseColumnName": "E-ISBN_sudoc_json", "expression": "grel:value.parseJson()['sudoc']['ppn']['title']", "onError": "set-to-blank" }, { "op": "core/column-addition", "description": "Script sémantique : création d'une colonne contenant le E-sudoc_title nettoyé", "engineConfig": { "facets": [], "mode": "row-based" }, "newColumnName": "E-sudoc_title_clean", "columnInsertIndex": 25, "baseColumnName": "E-sudoc_title", "expression": "grel:toLowercase(trim(value.replace(/\\u00A0/, ' '))).replace(/\\p{Punct}/,' ').replace(/\\u2019/, ' ').replace(/\\u200E/, ' ').replace(/\\s+/, ' ')", "onError": "set-to-blank" }, { "op": "core/column-addition", "description": "Script sémantique : préparation du calcul de distance", "engineConfig": { "facets": [], "mode": "row-based" }, "newColumnName": "E-min_clean_title", "columnInsertIndex": 25, "baseColumnName": "pub_title_clean", "expression": "grel:min(length(value),length(cells['E-sudoc_title_clean'].value))", "onError": "set-to-blank" }, { "op": "core/column-addition", "description": "Script sémantique : résultat du calcul de distance", "engineConfig": { "facets": [], "mode": "row-based" }, "newColumnName": "E-dist_title", "columnInsertIndex": 25, "baseColumnName": "E-min_clean_title", "expression": "grel:jarowinkler(stripAccents(substring(cells['pub_title_clean'].value,0,value)),stripAccents(substring(cells['E-sudoc_title_clean'].value,0,value)))", "onError": "set-to-blank" }, { "op": "core/column-removal", "description": "Suppression d'une colonne devenue inutile", "columnName": "E-sudoc_title" }, { "op": "core/column-removal", "description": "Suppression d'une colonne devenue inutile", "columnName": "E-min_clean_title" }, { "op": "core/column-addition", "description": "Script sémantique : création d'une colonne contenant la valeur 'NOK' si l'ISBN n'est pas électronique", "engineConfig": { "mode": "row-based", "facets": [] }, "newColumnName": "error_online_media", "columnInsertIndex": 25, "baseColumnName": "E-ISBN_sudoc_json", "expression": "grel:if(value!=null,if(value.parseJson()['sudoc']['ppn']['media']!='l','NOK',''),'')", "onError": "set-to-blank" }, { "op": "core/column-addition", "description": "Gestion des ppn multiples", "engineConfig": { "mode": "row-based", "facets": [] }, "newColumnName": "E-ISBN_multi-ppn", "columnInsertIndex": 25, "baseColumnName": "E-ISBN_sudoc_json", "expression": "grel:forEach(value.parseJson().sudoc,v,[v.ppn.media,v.ppn.content].join(':')).join(' ')", "onError": "set-to-blank" }, { "op": "core/column-addition", "description": "Test sur le type de média", "engineConfig": { "mode": "row-based", "facets": [] }, "newColumnName": "E-ISBN_multi-ppn_final", "columnInsertIndex": 25, "baseColumnName": "E-ISBN_multi-ppn", "expression": "grel:if(isBlank(value)==false,if(value.match(/.*l.*/)==null,value,''),'')", "onError": "set-to-blank" }, { "op": "core/column-split", "description": "Séparer le contenu de la colonne P-ISBN_multi_ppn_final en autant de colonnes qu'il y a de ppn", "engineConfig": { "mode": "row-based", "facets": [] }, "columnName": "E-ISBN_multi-ppn_final", "guessCellType": true, "removeOriginalColumn": true, "mode": "separator", "separator": " ", "regex": false, "maxColumns": 0 }, { "op": "core/column-addition", "description": "Script sémantique : création d'une colonne contenant le first_author nettoyé", "engineConfig": { "facets": [], "mode": "row-based" }, "newColumnName": "first_author_clean", "columnInsertIndex": 25, "baseColumnName": "first_author", "expression": "grel:toLowercase(trim(value.replace(/\\u00A0/, ' '))).replace(/\\p{Punct}/,' ').replace(/\\u2019/, ' ').replace(/\\u200E/, ' ').replace(/\\s+/, ' ')", "onError": "set-to-blank" }, { "op": "core/column-addition", "description": "Script sémantique : extraire l'auteur pour comparaison", "engineConfig": { "facets": [], "mode": "row-based" }, "newColumnName": "E-sudoc_author", "columnInsertIndex": 25, "baseColumnName": "E-ISBN_sudoc_json", "expression": "grel:value.parseJson()['sudoc']['ppn']['marcautrel']", "onError": "set-to-blank" }, { "op": "core/column-addition", "description": "Script sémantique : création d'une colonne contenant l'auteur sudoc nettoyé", "engineConfig": { "facets": [], "mode": "row-based" }, "newColumnName": "E-sudoc_author_clean", "columnInsertIndex": 25, "baseColumnName": "E-sudoc_author", "expression": "grel:toLowercase(trim(value.replace(/\\u00A0/, ' '))).replace(/\\p{Punct}/,' ').replace(/\\u2019/, ' ').replace(/\\u200E/, ' ').replace(/\\s+/, ' ')", "onError": "set-to-blank" }, { "op": "core/column-addition", "description": "Script sémantique : préparation du calcul de distance", "engineConfig": { "facets": [], "mode": "row-based" }, "newColumnName": "E-min_clean_author", "columnInsertIndex": 25, "baseColumnName": "first_author_clean", "expression": "grel:min(length(value),length(cells['E-sudoc_author_clean'].value))", "onError": "set-to-blank" }, { "op": "core/column-addition", "description": "Script sémantique : résultat du calcul de distance", "engineConfig": { "facets": [], "mode": "row-based" }, "newColumnName": "E-dist_author", "columnInsertIndex": 25, "baseColumnName": "E-min_clean_author", "expression": "grel:if(value!=0,(jarowinkler(stripAccents(substring(cells['first_author_clean'].value,0,value)),stripAccents(substring(cells['E-sudoc_author_clean'].value,0,value)))),'')", "onError": "set-to-blank" }, { "op": "core/column-removal", "description": "Suppression d'une colonne devenue inutile", "columnName": "E-sudoc_author" }, { "op": "core/column-removal", "description": "Suppression d'une colonne devenue inutile", "columnName": "E-min_clean_author" }, { "op": "core/column-addition-by-fetching-urls", "description": "Script sémantique : création d'une colonne contenant les informations du Sudoc à partir du print_identifier grâce au webservice 'isbnbacon'", "engineConfig": { "mode": "row-based", "facets": [] }, "newColumnName": "P-ISBN_sudoc_json", "columnInsertIndex": 25, "baseColumnName": "print_identifier", "urlExpression": "grel:if(value!=null,'https://bacon.abes.fr/isbnbacon/'+value+'.json','')", "onError": "set-to-blank", "delay": 10 }, { "op": "core/column-addition", "description": "Script sémantique : création d'une colonne contenant le titre sudoc", "engineConfig": { "facets": [], "mode": "row-based" }, "newColumnName": "P-sudoc_title", "columnInsertIndex": 25, "baseColumnName": "P-ISBN_sudoc_json", "expression": "grel:if(cells['E-ISBN_sudoc_json']==null,value.parseJson()['sudoc']['ppn']['title'],'')", "onError": "set-to-blank" }, { "op": "core/column-addition", "description": "Script sémantique : création, en 16ème position, d'une colonne contenant le P-sudoc_title nettoyé", "engineConfig": { "facets": [], "mode": "row-based" }, "newColumnName": "P-sudoc_title_clean", "columnInsertIndex": 25, "baseColumnName": "P-sudoc_title", "expression": "grel:toLowercase(trim(value.replace(/\\u00A0/, ' '))).replace(/\\p{Punct}/,' ').replace(/\\u2019/, ' ').replace(/\\u200E/, ' ').replace(/\\s+/, ' ')", "onError": "set-to-blank" }, { "op": "core/column-addition", "description": "Script sémantique : préparation, en 17ème position, du calcul de distance", "engineConfig": { "facets": [], "mode": "row-based" }, "newColumnName": "P-min_clean_title", "columnInsertIndex": 25, "baseColumnName": "pub_title_clean", "expression": "grel:min(length(value),length(cells['P-sudoc_title_clean'].value))", "onError": "set-to-blank" }, { "op": "core/column-addition", "description": "Script sémantique : résultat du calcul de distance, en 18ème position", "engineConfig": { "facets": [], "mode": "row-based" }, "newColumnName": "P-dist_title", "columnInsertIndex": 25, "baseColumnName": "P-min_clean_title", "expression": "grel:if(cells['P-min_clean_title'].value!=0,jarowinkler(stripAccents(substring(cells['pub_title_clean'].value,0,value)),stripAccents(substring(cells['P-sudoc_title_clean'].value,0,value))),'')", "onError": "set-to-blank" }, { "op": "core/column-removal", "description": "Suppression d'une colonne devenue inutile", "columnName": "P-sudoc_title" }, { "op": "core/column-removal", "description": "Suppression d'une colonne devenue inutile", "columnName": "P-min_clean_title" }, { "op": "core/column-addition", "description": "Script sémantique : création d'une colonne contenant la valeur 'NOK' si l'ISBN n'est pas papier", "engineConfig": { "mode": "row-based", "facets": [] }, "newColumnName": "erreur_print_media", "columnInsertIndex": 25, "baseColumnName": "P-ISBN_sudoc_json", "expression": "grel:if(value!=null,if(value.parseJson()['sudoc']['ppn']['media']!='a','NOK',''),'')", "onError": "set-to-blank" }, { "op": "core/column-addition", "description": "Gestion des ppn multiples", "engineConfig": { "mode": "row-based", "facets": [] }, "newColumnName": "P-ISBN_multi-ppn", "columnInsertIndex": 25, "baseColumnName": "P-ISBN_sudoc_json", "expression": "grel:forEach(value.parseJson().sudoc,v,[v.ppn.media,v.ppn.content].join(':')).join(' ')", "onError": "set-to-blank" }, { "op": "core/column-addition", "description": "Test sur le type de média", "engineConfig": { "mode": "row-based", "facets": [] }, "newColumnName": "P-ISBN_multi-ppn_final", "columnInsertIndex": 25, "baseColumnName": "P-ISBN_multi-ppn", "expression": "grel:if(isBlank(value)==false,if(value.match(/.*a.*/)==null,value,''),'')", "onError": "set-to-blank" }, { "op": "core/column-split", "description": "Séparer le contenu de la colonne P-ISBN_multi_ppn_final en autant de colonnes qu'il y a de ppn", "engineConfig": { "mode": "row-based", "facets": [] }, "columnName": "P-ISBN_multi-ppn_final", "guessCellType": true, "removeOriginalColumn": true, "mode": "separator", "separator": " ", "regex": false, "maxColumns": 0 }, { "op": "core/column-addition", "description": "Script sémantique : extraire l'auteur du json pour comparaison", "engineConfig": { "facets": [], "mode": "row-based" }, "newColumnName": "P-sudoc_author", "columnInsertIndex": 25, "baseColumnName": "P-ISBN_sudoc_json", "expression": "grel:if(cells['E-sudoc_author']==null,value.parseJson()['sudoc']['ppn']['marcautrel'],'')", "onError": "set-to-blank" }, { "op": "core/column-addition", "description": "Script sémantique : création d'une colonne contenant l'auteur sudoc nettoyé", "engineConfig": { "facets": [], "mode": "row-based" }, "newColumnName": "P-sudoc_author_clean", "columnInsertIndex": 25, "baseColumnName": "P-sudoc_author", "expression": "grel:toLowercase(trim(value.replace(/\\u00A0/, ' '))).replace(/\\p{Punct}/,' ').replace(/\\u2019/, ' ').replace(/\\u200E/, ' ').replace(/\\s+/, ' ')", "onError": "set-to-blank" }, { "op": "core/column-addition", "description": "Script sémantique : préparation du calcul de distance", "engineConfig": { "facets": [], "mode": "row-based" }, "newColumnName": "P-min_clean_author", "columnInsertIndex": 25, "baseColumnName": "first_author_clean", "expression": "grel:min(length(value),length(cells['P-sudoc_author_clean'].value))", "onError": "set-to-blank" }, { "op": "core/column-addition", "description": "Script sémantique : résultat du calcul de distance", "engineConfig": { "facets": [], "mode": "row-based" }, "newColumnName": "P-dist_author", "columnInsertIndex": 25, "baseColumnName": "P-min_clean_author", "expression": "grel:if(value!=0,(jarowinkler(stripAccents(substring(cells['first_author_clean'].value,0,value)),stripAccents(substring(cells['P-sudoc_author_clean'].value,0,value)))),'')", "onError": "set-to-blank" }, { "op": "core/column-removal", "description": "Suppression d'une colonne devenue inutile", "columnName": "P-sudoc_author" }, { "op": "core/column-removal", "description": "Suppression d'une colonne devenue inutile", "columnName": "P-min_clean_author" }, { "op": "core/text-transform", "description": "Script syntaxique : ne conserve que les quatre premiers caractères contenus dans le date_monograph_published_online, à condition qu'ils respectent le format YYYY. Sinon, informe d'une erreur de format", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "date_monograph_published_online", "expression": "grel:if(value.match(/.*(\\d{4}).*/)[0]==null,value+' : format incorrect',value.match(/.*(\\d{4}).*/)[0])", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : ne conserve que les quatre premiers caractères contenus dans le date_last_issue_online, à condition qu'ils respectent le format YYYY. Sinon, informe d'une erreur de format", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "date_monograph_published_print", "expression": "grel:if(isNonBlank(value),if(value.match(/.*(\\d{4}).*/)[0]==null,value+' : format incorrect',value.match(/.*(\\d{4}).*/)[0]),value)", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/column-addition", "description": "Script sémantique : extraire la date pour comparaison", "engineConfig": { "facets": [], "mode": "row-based" }, "newColumnName": "E-sudoc_date", "columnInsertIndex": 19, "baseColumnName": "E-ISBN_sudoc_json", "expression": "grel:toString(value.parseJson()['sudoc']['ppn']['pubdate'])", "onError": "set-to-blank" }, { "op": "core/column-addition", "description": "Script sémantique : crée une nouvelle colonne, résultat de la comparaison sur les dates de l'électronique", "engineConfig": { "facets": [], "mode": "row-based" }, "newColumnName": "E-sudoc_date_check", "columnInsertIndex": 20, "baseColumnName": "E-sudoc_date", "expression": "grel:if(isNonBlank(cells['date_monograph_published_online'].value),(if(contains(cells['date_monograph_published_online'].value,'format incorrect'),'',(if(value!=cells['date_monograph_published_online'].value,value,'')))),'')", "onError": "set-to-blank" }, { "op": "core/column-removal", "description": "Suppression d'une colonne devenue inutile", "columnName": "E-sudoc_date" }, { "op": "core/column-addition", "description": "Script sémantique : extraire la date pour comparaison", "engineConfig": { "facets": [], "mode": "row-based" }, "newColumnName": "P-sudoc_date", "columnInsertIndex": 18, "baseColumnName": "P-ISBN_sudoc_json", "expression": "grel:toString(value.parseJson()['sudoc']['ppn']['pubdate'])", "onError": "set-to-blank" }, { "op": "core/column-addition", "description": "Crée une nouvelle colonne, résultat de la comparaison sur les dates du papier", "engineConfig": { "facets": [], "mode": "row-based" }, "newColumnName": "P-sudoc_date_check", "columnInsertIndex": 19, "baseColumnName": "P-sudoc_date", "expression": "grel:if(isNonBlank(cells['date_monograph_published_print'].value),(if(contains(cells['date_monograph_published_print'].value,'format incorrect'),'',(if(value!=cells['date_monograph_published_print'].value,value,'')))),'')", "onError": "set-to-blank" }, { "op": "core/column-removal", "description": "Suppression d'une colonne devenue inutile", "columnName": "P-sudoc_date" }, { "op": "core/column-addition", "description": "Script syntaxique : doublons sur le publication_title", "engineConfig": { "mode": "row-based", "facets": [] }, "newColumnName": "publication_title_doublon", "columnInsertIndex": 27, "baseColumnName": "publication_title", "expression": "grel:forNonBlank(value,v,facetCount(v,'value','publication_title'),'')", "onError": "set-to-blank" }, { "op": "core/text-transform", "description": "Script syntaxique : vérifie qu'aucun champ du publication_title ne soit vide", "engineConfig": { "mode": "row-based", "facets": [] }, "columnName": "publication_title", "expression": "grel:if(isBlank(value)==true,'titre manquant',value)", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/column-addition", "description": "Script syntaxique : doublons sur le print_identifier", "engineConfig": { "mode": "row-based", "facets": [] }, "newColumnName": "print_identifier_doublon", "columnInsertIndex": 28, "baseColumnName": "print_identifier", "expression": "grel:forNonBlank(value,v,facetCount(v,'value','print_identifier'),'')", "onError": "set-to-blank" }, { "op": "core/column-addition", "description": "Script syntaxique : doublons sur le online_identifier", "engineConfig": { "mode": "row-based", "facets": [] }, "newColumnName": "online_identifier_doublon", "columnInsertIndex": 29, "baseColumnName": "online_identifier", "expression": "grel:forNonBlank(value,v,facetCount(v,'value','online_identifier'),'')", "onError": "set-to-blank" }, { "op": "core/text-transform", "description": "Script syntaxique : champ obligatoirement vide", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "date_first_issue_online", "expression": "grel:if(isBlank(value)!=true,value+' : doit être vide',value)", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : champ obligatoirement vide", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "num_first_vol_online", "expression": "grel:if(isBlank(value)!=true,value+' : doit être vide',value)", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : champ obligatoirement vide", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "num_first_issue_online", "expression": "grel:if(isBlank(value)!=true,value+' : doit être vide',value)", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : champ obligatoirement vide", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "date_last_issue_online", "expression": "grel:if(isBlank(value)!=true,value+' : doit être vide',value)", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : champ obligatoirement vide", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "num_last_vol_online", "expression": "grel:if(isBlank(value)!=true,value+' : doit être vide',value)", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : champ obligatoirement vide", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "num_last_issue_online", "expression": "grel:if(isBlank(value)!=true,value+' : doit être vide',value)", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : aucun champ vide", "engineConfig": { "mode": "row-based", "facets": [] }, "columnName": "title_url", "expression": "grel:if(isBlank(value)==true,'URL obligatoire',value)", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/column-addition", "description": "Script syntaxique : la partie fixe du title_url mise de côté, la partie évolutive restante correspond-elle au title_id ? Test I ATTENTION : A ACTUALISER AVANT D'UTILISER LE SCRIPT : remplacer [X] par la partie fixe de l'URL", "engineConfig": { "facets": [], "mode": "row-based" }, "newColumnName": "title_url_bis", "columnInsertIndex": 10, "baseColumnName": "title_url", "expression": "grel:value.replace('[X]','')", "onError": "set-to-blank" }, { "op": "core/text-transform", "description": "Script syntaxique : la partie fixe du title_url mise de côté, la partie évolutive restante correspond-elle au title_id ? Test II", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "title_id", "expression": "grel:if(cells[\"title_url_bis\"].value==cells[\"title_id\"].value,value,\"erreur ? \"+value)", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : champ obligatoirement vide", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "embargo_info", "expression": "grel:if(isBlank(value)!=true,value+' : doit être vide',value)", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : contient obligatoirement « fulltext », « selected articles » ou abstract", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "coverage_depth", "expression": "grel:if(isNotNull(value.match(/fulltext|selected articles|abstract/)),value,value+' format incorrect')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : ne peut pas être vide", "engineConfig": { "mode": "row-based", "facets": [] }, "columnName": "publisher_name", "expression": "grel:if(isBlank(value)!=false,'doit être renseigné',value)", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : contient obligatoirement « monograph »", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "publication_type", "expression": "grel:if(isNotNull(value.match(/monograph/)),value,value+' : format incorrect')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : le contenu du monograph_volume, lorsqu'il n'est pas numérique, suit-il une cohérence ?", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "monograph_volume", "expression": "grel:if(isNotNull(value.match(/[0-9]*/)),value,'cohérent ? '+value)", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : le contenu du monograph_edition, lorsqu'il n'est pas numérique, suit-il une cohérence ?", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "monograph_edition", "expression": "grel:if(isNotNull(value.match(/[0-9]*/)),value,'cohérent ? '+value)", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : le contenu du first_author est-il une suite de lettres, majuscules ou minuscules, formant un mot unique ?", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "first_author", "expression": "grel:if(isNull(value.match(/[a-zA-Z]*/))==true,value+ ' : erreur ?',value)", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : champ obligatoirement vide", "engineConfig": { "mode": "row-based", "facets": [] }, "columnName": "preceding_publication_title_id", "expression": "grel:if(isBlank(value)!=true,value+' : doit être vide',value)", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : contient obligatoirement P ou F", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "access_type", "expression": "grel:if(isNotNull(value.match(/[PF]/)),value,value+' : format incorrect')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : print_identifier et online_identifier ne peuvent être vides à la fois, TEST 1", "engineConfig": { "mode": "row-based", "facets": [] }, "columnName": "print_identifier", "expression": "grel:if(cells.print_identifier.value.length()==0,(if(cells.online_identifier.value.length()==0,'manque ISBN',value)),value)", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : print_identifier et online_identifier ne peuvent être vides à la fois, TEST 2", "engineConfig": { "mode": "row-based", "facets": [] }, "columnName": "online_identifier", "expression": "grel:if(cells.print_identifier.value=='manque ISBN',(if(cells.online_identifier.value.length()==0,'manque ISBN',value)),value)", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : aucun e-ISBN mais un p-ISBN : s'agit-il d'un e-book numérique natif ?", "engineConfig": { "mode": "row-based", "facets": [] }, "columnName": "print_identifier", "expression": "grel:if(isBlank(value)==true,'e-book natif numérique ?',value)", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : tous les eISBN doivent être renseignés, y compris si le livre a été numérisé (demande à faire auprès du CIEPS)", "engineConfig": { "mode": "row-based", "facets": [] }, "columnName": "online_identifier", "expression": "grel:if(isBlank(value)==true,'ISBN obligatoire',value)", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : p-ISBN non conforme I", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "print_identifier", "expression": "grel:value.replace('-','')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : p-ISBN non conforme II", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "print_identifier", "expression": "grel:if(value.match(/^(97(8|9))?\\d{9}(\\d|X)$/)==null,value+\" n'est pas un isbn conforme\",value)", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : e-ISBN non conforme I", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "online_identifier", "expression": "grel:value.replace('-','')", "onError": "keep-original", "repeat": false, "repeatCount": 10 }, { "op": "core/text-transform", "description": "Script syntaxique : e-ISBN non conforme II", "engineConfig": { "facets": [], "mode": "row-based" }, "columnName": "online_identifier", "expression": "grel:if(value.match(/^(97(8|9))?\\d{9}(\\d|X)$/)==null,value+\" n'est pas un isbn conforme\",value)", "onError": "keep-original", "repeat": false, "repeatCount": 10 } ]

Avant d’appliquer ces scripts dans OpenRefine et après avoir déposé les fichiers sur un serveur dédié, cinq critères syntaxiques sont préalablement vérifiés :

  • la syntaxe du nom de fichier [6.5.1] (la numérotation entre crochets renvoie à la documentation KBART Phase II)
  • la présence de vingt-cinq colonnes, correctement nommées et ordonnées [6.4.4, 6.4.5]
  • l’obligation de renseigner certaines colonnes, d’en laisser d’autres vides, selon le type de document [6.6]
  • l’encodage du texte en UTF-8 [6.4.3]
  • le séparateur de champs, qui doit être la tabulation [6.4.1]

Ces critères doivent être remplis pour passer à l’étape suivante. Ils sont par ailleurs obligatoires pour un chargement dans la base.
Si un fichier ne répond pas à l’un de ces critères, l’éditeur en est informé. L’évaluation ne peut aller plus loin avant qu’une nouvelle version, corrigée, ne nous soit parvenue.

Dans le cas contraire, le fichier est chargé dans OpenRefine et le script correspondant au type de document est appliqué. Le script applicable aux périodiques contient 97 opérations. Celui pour les e-books, 145. Ce nombre peut varier selon la qualité du fichier, certaines opérations n’ayant pas lieu si aucune correction n’est nécessaire.

Les erreurs de type syntaxique sont mentionnées directement dans la cellule qui les contient. En revanche, les opérations de type sémantique nécessitent de créer des colonnes supplémentaires pour l’affichage des erreurs. En effet, les erreurs sémantiques sont des erreurs potentielles, qui doivent être vérifiées avant d’être validées. Il est nécessaire, pour comprendre ce choix, de savoir que nous communiquons à l’éditeur un fichier, au format html, qui accompagne le rapport écrit transmis après chaque évaluation. Ce fichier est le résultat d’un différentiel entre le fichier KBART qui nous a été transmis par l’éditeur et le fichier évalué sur lequel le script a été appliqué et enrichi des corrections de celui qui l’évalue. L’outil utilisé est DAFF.

Les scripts ont donc été pensés selon le type de document, selon le type d’erreur, mais aussi selon l’usage qui en est fait par les éditeurs. Disposer de ce fichier html leur permet, grâce à un code couleur, de repérer facilement les lignes qui ont été modifiées lors de l’évaluation, qu’il s’agisse d’une modification automatisée grâce au script ou d’une modification manuelle effectuée par l’évaluateur.

Pour résumer, prenons deux exemples d’opérations : celui du format des identifiants, ISSN et ISBN, qui est une opération syntaxique ; celui des métarevues, qui permet de déceler la présence de titres non déployés dans le fichier.
Un identifiant non conforme sera décelé par le script sans équivoque. Un ISSN sans tiret ou contenant la lettre ‘X’ en deuxième position contient nécessairement une erreur.
En revanche, le script permettra de repérer une date de début de couverture (date_first_issue_online) inférieure à la date de début de la publication contenue dans le SUDOC, indice susceptible de révéler la présence d’une métarevue non déployée, mais ne sera pas en mesure d’apporter une réponse plus aboutie afin d’aider l’éditeur à corriger son fichier. Une intervention humaine sera nécessaire afin de consulter le registre ISSN et enrichir le fichier des titres de la métarevue qui en sont absents.

Vous comprenez maintenant pourquoi certaines modifications du fichier par le script doivent être faites non pas directement dans les cellules que contient la version qui nous est livrée par l’éditeur, mais dans des colonnes supplémentaires : pour les tests sémantiques, l’évaluateur modifie les cellules du fichier qui contiennent des erreurs, tout en s’appuyant sur les informations contenues dans les colonnes générées par le script.

Une fois le fichier corrigé des erreurs syntaxiques et sémantiques qu’il contient, il est exporté d’OpenRefine.
Le différentiel est alors généré et son résultat transmis à l’éditeur comme illustration des informations contenues dans le rapport.

Peut-être vous êtes-vous déjà lancé dans l’utilisation des scripts avant d’en arriver là dans la lecture du billet. J’en serais heureux ! Peut-être alors vous êtes-vous trouvé confronté à certaines incompréhensions dans l’analyse du résultat. Rien de plus normal, surtout si vos interrogations portent sur les deux points suivants :

  • les scripts ont été élaborés sous la version 2.5 d’OpenRefine, qui s’appelait encore GoogleRefine à l’époque de sa conception, c’est-à-dire en 2011. Depuis, deux nouvelles versions ont vu le jour. Mais ces dernières sont des versions beta. Nous avons préféré nous appuyer sur la dernière version stable, la 2.5. Bien que les scripts semblent compatibles avec les versions plus récentes, tous les tests n’ont pas encore été effectués pour le confirmer.
  • la colonne ‘P-dist_author’ du script e-books ne laisse apparaître aucune information, voire n’a pas été générée. Rien de plus normal : elle contient le résultat d’un calcul de distance entre les chaînes de caractères contenues dans le ‘publication_title’ et la zone 200 de la notice SUDOC renvoyée par l’ISBN papier. Or ce calcul de distance s’appuie sur une fonction présente sur le serveur qui héberge OpenRefine à l’Abes. Vous ne pouvez donc pas y faire appel. Cette restriction est valable pour d’autres opérations. Notez, pour les plus curieux, qu’OpenRefine dispose de tels outils par défaut.

Ne pas être en mesure d’exploiter pleinement ces scripts pourrait être frustrant… C’est pourquoi nous proposons à ceux qui souhaitent en savoir plus sur la manière de les utiliser de rejoindre le premier des CERCLES mené dans le cadre de BACON. Pour en savoir plus, rendez-vous au prochain (et dernier) billet de la série.

N.B. : les scripts communiqués correspondent à une version. Ils ne sont en rien figés et nous serions très heureux de les enrichir de vos suggestions.

Cyril Leroy

OpenRefine au service de BACON : quelle évaluation pour les fichiers KBART ? [2] – Un outil : OpenRefine

[Lire le billet qui introduit cette série « OpenRefine au service de BACON : quelle évaluation pour les fichiers KBART ? »]

OpenRefine est un outil open source conçu pour manipuler des données dont la qualité nécessite un traitement. Mais il permet bien plus que de nettoyer un fichier tabulé des scories qu’il contient. Comparable à Excel, son principal intérêt est de permettre l’appel à des services web. Il est alors possible, et facile, de comparer le contenu d’un fichier avec une base de référence disposant d’une API.

Ce billet est un accompagnement dans vos premiers pas avec OpenRefine : comment l’installer, charger un fichier, effectuer ses premiers traitements.
Étant donné le nombre de tutoriels déjà disponibles sur cet outil, il sera surtout l’occasion de vous communiquer une bibliographie.

     1. Installation

OpenRefine est disponible sous Windows, Mac et Linux. Son installation s’effectue sans difficulté, quel que soit l’environnement sous lequel vous évoluez : il suffit de lancer le fichier d’installation correspondant au vôtre, téléchargeable depuis le site officiel.
Un environnement Java est requis.
Vous noterez, sur la même page, la liste des extensions qu’il est possible d’installer afin, par exemple, de permettre les exports en RDF.

     2. Chargement d’un fichier

Après avoir lancé OpenRefine, votre navigateur par défaut offre un nouvel onglet. Vous voyez alors apparaître :

accueil_OR

A gauche, trois onglets permettent de créer un projet (onglet actif sur l’illustration), d’ouvrir un projet existant ou d’importer un projet précédemment exporté.

A l’import, OpenRefine accepte de multiples formats. Pour illustrer notre propos, l’exemple utilisé sera celui d’un fichier tabulé (.tsv), ayant pour séparateur la tabulation, encodé en UTF-8. Ce fichier est issu de BACON : « Lavoisier_Global_AllJournals_2016-07-01.txt »

Pour importer un tel fichier après son téléchargement, cliquer sur « Parcourir », sélectionner le fichier dans l’arborescence de l’ordinateur puis cliquer sur « Next ».

Une nouvelle fenêtre apparaît, qui permet de choisir différentes options. Cette copie d’écran reproduit la partie inférieure de l’écran :

chargement_OR

Les options sélectionnées ne correspondent pas à la configuration proposée par défaut, mais aux besoins inhérents au fichier ainsi qu’aux traitements que nous allons opérer.
Il s’agit bien d’un fichier tabulé (fenêtre de gauche à fond bleu), dont le séparateur est la tabulation (« tabs »). La première ligne contient les intitulés de colonnes et doit donc être considérée comme telle (« Parse next »). Il ne nous reste plus qu’à cliquer sur « Create Project ».

     3. Présentation de l’interface

Appliquer des traitements sur les données que contient un projet peut s’opérer de deux manières complémentaires : par l’interface graphique ou en appliquant un script. OpenRefine accepte trois langages de programmation différents : GREL (General Refine Expression Language), Jython et Clojure.
Lors de nos traitements, nous utilisons GREL. Avec une  subtilité : la fonctionnalité qui permet d’appliquer un script accepte en réalité du Json, qui encapsule l’un des trois langages, dont le GREL.

Par exemple :

 {
 "op": "core/column-addition",
 "description": "Contient obligatoirement P ou F",
 "engineConfig": {
 "mode": "row-based",
 "facets": []
 },
 "newColumnName": "access_type_format",
 "columnInsertIndex": 55,
 "baseColumnName": "access_type",
 "expression": "grel:if(isNotNull(value.match(/[PF]/)),value,value+' : format incorrect')",
 "onError": "set-to-blank"
 }

Ce script vérifie le contenu des cellules de l’access_type, cette colonne du fichier KBART qui informe sur le type d’accès pour un titre : payant (« P ») ou gratuit (« F »). Il respecte la syntaxe Json mais, comme vous pouvez le remarquer, la ligne 11, intitulée « expression » et qui comporte l’appel aux fonctions, déclare en prémisse que le contenu de l’expression suit la syntaxe « grel ».

La méthode par script n’est pas la plus évidente à mettre en œuvre lors d’une première utilisation. La prise en main d’OpenRefine gagnera à se faire par l’interface graphique. Mais, très vite, il est nécessaire d’avoir recours à l’un des langages de programmation, nombre de fonctions n’étant pas accessibles par l’interface.

En revanche, pour s’initier au GREL, l’interface est un excellent outil qui permettra d’ailleurs un gain de temps considérable. En effet, plutôt que de coder directement en Json, mieux vaut utiliser l’interface graphique pour renseigner les expressions GREL. Il sera ensuite toujours possible de récupérer, par une extraction de l’historique, les expressions GREL qui apparaîtront alors directement revêtues de leur habit de Json.
Voilà pourquoi les deux méthodes sont complémentaires.

Pour reprendre l’exemple précédent, voici la méthode a priori la plus simple pour parvenir au résultat escompté.

  • dans l’interface, sélectionner la flèche correspondant à la colonne sur laquelle mener l’opération. Sélectionner « Edit cells » > « Transform ».

access_type1_OR

  • cette action a pour conséquence l’ouverture d’une nouvelle fenêtre, depuis laquelle nous allons renseigner l’expression correspondant à l’opération que nous voulons mener (2), en GREL (1). Le résultat sur les cellules est directement visible (3).
    [Les valeurs « l » (l. 1) et « F » (l.3) ont été modifiées pour les besoins de l’exemple]

access_type2_OR

Nous ne nous arrêterons pas dans le détail sur la manière dont l’expression est construite. Ce qui nous importe ici est le résultat obtenu et le moyen de le reproduire facilement en récupérant le script au format Json.

  • pour ce faire, après avoir appliqué l’opération en cliquant sur « OK », nous allons sélectionner l’option « Extract » depuis l’historique.
    Remarquons que trois actions ont été menées jusqu’à présent sur ce projet : les opérations 1 et 2 correspondent à l’édition des lignes 1 et 3 de la colonne access_type afin de rendre l’exemple plus parlant. La troisième, celle qui nous intéresse réellement, correspond à la vérification du contenu de cette colonne : si l’une des cellules qui la constituent contient une valeur autre que « P » ou « F », alors la valeur initiale doit apparaître, suivie de la mention « format incorrect ». Dans le cas contraire, seule la valeur initiale doit apparaître.

access_type3_OR

  • après avoir cliqué sur « Extract » une nouvelle fenêtre nous permet de sélectionner la partie du code, formaté en Json, qui nous intéresse. Ici, seulement celle qui correspond à la troisième étape, d’ailleurs la seule accessible, l’édition manuelle de contenu ne pouvant être exportée.

access_type4_OR

Il est alors facile de copier le code afin de le conserver pour une utilisation ultérieure. Il suffira, sur un nouveau projet, de coller le code correspondant, au format Json, dans la fenêtre accessible en cliquant sur « Apply » dans l’historique puis de valider à l’aide de « Perform Operations »

access_type5_OR

 

access_type6_OR

Vous avez peut-être remarqué la présence d’une différence entre le script tel que je vous l’ai présenté en début de ce chapitre et celui qui a été généré par OR et copié tel quel dans la fenêtre « Apply Operation History » ci-dessus.
Il s’agit de la « description » du code. En Json, les commentaires apparaissent dans cette partie, en texte libre pourvu que le texte soit entre guillemets. Pour une meilleure lisibilité et afin d’apporter des éléments plus précis que ceux contenus dans la description générée automatiquement par OpenRefine, son contenu a été modifié dans le script du début de chapitre.

A venir : Dans le prochain billet, nous vous communiquerons les scripts utilisés afin d’évaluer les fichiers KBART.

Bibliographie :

Cyril Leroy

OpenRefine au service de BACON : quelle évaluation pour les fichiers KBART ? [1] – Introduction

Cette série de billets exposera la méthode d’évaluation appliquée aux fichiers KBART, transmis à l’Abes par les éditeurs francophones ayant accepté de collaborer avec nous.
Pour le dernier d’entre eux, l’occasion sera donnée d’exposer une nouvelle déclinaison du dispositif CERCLES, appliquée à BACON.

  1. Introduction (ce billet)
  2. Un outil : OpenRefine
  3. Cas pratique
  4. Dispositif CERCLES dans le cadre de BACON

 

 Logo Bacon

La BAse de COnnaissance Nationale (BACON) est un entrepôt de métadonnées libres pour le signalement de la documentation électronique.
Son contenu, exposé sur bacon.abes.fr, peut être interrogé et téléchargé par webservices ou via l’interface graphique du site web.

Le modèle qui organise la base est conforme à la recommandation KBART NISO-RP-9-2014. Le premier niveau d’accès au contenu est celui du titre, pour les livres électroniques comme pour les périodiques. L’ISBN et l’ISSN électroniques constituent les portes d’entrée sur l’ensemble des métadonnées contenues dans les 25 champs de la recommandation.

Au second niveau, les titres sont regroupés par bouquets et masterlists. Il est en effet possible de différencier les fichiers mis à disposition selon leur nature : les masterlists décrivent l’ensemble du contenu d’une plate-forme pour un éditeur donné ; les bouquets correspondent aux offres commerciales proposées.

BACON contient, à ce jour, 178 bouquets et masterlists de ressources proposées par l’édition scientifique francophone. Ce résultat, non définitif, a été atteint en informant les éditeurs de l’intérêt d’appliquer la recommandation KBART pour l’amélioration de la qualité des métadonnées qui permettent le signalement et l’accès à la documentation électronique. Corriger à la source bénéficie à l’ensemble des intervenants qui redistribuent ou utilisent ces métadonnées.

Les éditeurs sensibles à nos arguments, qui acceptent de mettre en place un circuit de production de fichiers au format KBART, se voient proposer une évaluation des fichiers ainsi produits et une expertise sur la recommandation, avant de voir leurs fichiers chargés dans la base.

Pour mener à bien les évaluations, nous mettons en œuvre une procédure qui s’articule principalement autour d’un outil : OpenRefine.

Cyril Leroy

CERCLES : retour d’expérience du SCD de l’Université de Picardie Jules Verne sur le corpus CAIRN

Les origines

Les questions sur SUCAT

cercles_upjv

Nouvelle adjointe à la gestion de la bibliothèque numérique dans mon établissement, et chargée du signalement des e-books, je me suis posé beaucoup de questions quant au traitement de ces ressources. J’ai étudié de près les avantages et inconvénients de l’exemplarisation automatique, notamment en terme de qualité et de complétude des notices, et lancé une question ouverte aux catalogueurs de ressources en ligne sur SUCAT (ndlr : la liste de diffusion des catalogueurs du réseau Sudoc), posant les questions qui me taraudaient, intitulée : « Aux catalogueurs des bibliothèques numériques ».

Les réponses ont afflué, l’ABES a également répondu que cela figurait parmi ses préoccupations actuelles.

La mise en place de CERCLES

Des pistes de résolution et une expérimentation avec un SCD sur le principe de mutualisation du traitement de la qualité des données de ressources électroniques dans le Sudoc étant déjà en cours, l’ABES m’a proposé de faire partie du projet naissant.

L’engagement

Avec l’accord de ma hiérarchie, un acte d’engagement a été signé entre mon établissement et l’ABES, mentionnant le périmètre d’action et les délais engagés.

Délimitation du périmètre d’action :

Un corpus clos a été établi par l’ABES, avec l’édition d’un tableau de PPN, édité à une date D, et dans lequel tout nouveau versement n’apparaîtra pas, soit une liste de 4852 notices à traiter.

Axes d’enrichissements :

L’accord initial prévoyait une mise en lien des 7xx, et le travail collatéral : indicateurs, codes de fonction, création d’autorités au besoin.

Évaluation en amont des notices du corpus :

Un travail préalable, sur un échantillon de 50 notices, m’a permis de faire une estimation du temps passé, mais aussi et surtout de constater nombre de surprises, et donc, d’élaborer quelques changements d’orientation, exposés et acceptés par l’ABES : ainsi, les notices dans lesquelles les auteurs étaient déjà liés, ont été exclues de mon champ d’action. Les notices dans lesquelles des liens étaient à créer sont restées à ma charge (1484 PPN).
Pour celles-ci, je me suis engagée, en plus de créer les liens et les notices d’autorité le cas échéant (+ travail collatéral pré-cité) :

  • à contrôler la construction des 200 ($f $g) ;
  • à redistribuer en conséquence les zones et codes de fonction en 7xx ;
  • à assurer les modifications suivantes : caractères parasites, arobase mal positionné, désordre des sous-zones en 200 ;
  • à signaler tout problème d’URL (ABES et Cairn).

Mon périmètre initial a été certes réduit (on est passé de 4852 notices à 1484), mais les modifications apportées sont finalement plus nombreuses et plus poussées.

Le chantier d’enrichissement

Traitement en pratique

By_Horla_Varlan_CC_BY

Étape 1 : j’ouvre les outils dont j’ai besoin

  • l’espace collaboratif CERCLES (les 3 documents « tableau de bord », « suivi pour info réseau » et « tableau de suivi »)
  • WinIBW
  • la plateforme « Cairn.info« 

Étape 2 : j’affiche la notice WinIBW à étudier (je copie/colle le PPN à partir de mon « tableau de suivi »)

Étape 3 : je copie/colle l’URL de la zone 859 dans « Cairn.info » pour vérifier l’URL fournisseur et accéder à la ressource

Si l’URL est erronée, je recherche par titre puis demande de modification de la zone 859 à l’ABES via le guichet d’assistance + signalement à Cairn + transmission au Correspondant Catalogage pour diffusion de l’information sur les listes, afin que les bibliothèques actualisent leur E856. Je corrige immédiatement la zone E856 de mon exemplaire.

Étape 4 : j’ouvre le document dans « Cairn.info » (en PDF ou en HTML) pour accéder à la page de titre notamment, source principale de catalogage. Je commence le travail de vérification / enrichissement :

  • vérification de la conformité de la zone 200 $a, $e ; $f ; $g, et corrections le cas échéant
    • toujours, les auteurs, toutes responsabilités confondues, sont présents en $f
    • souvent, il manque $e
    • souvent, $e est mal placée (après $f)
  • redistribution des 7XX et des codes de fonction, corrections
    • toujours, il n’y a que des 700 et 701, pas de 702 (beaucoup d’auteurs en réalité « directeurs »)
    • toujours, les indicateurs des 7XX sont erronés
  • mise en lien des 7XX
    • création d’Autorités Personnes Physiques (APP) le cas échéant
    • vérification des liens déjà faits : parfois, les liens sont erronés (homonymes)
    • vérification des données codées des APP (zone 106 en particulier)
    • si un doublon APP est identifié, transmission au Correspondant Autorité
  • vérification de l’indication du type de document : 200 $b ou 181-182
    • parfois, les deux coexistent : suppression de 200 $b
  • vérification de la zone 300, et corrections le cas échéant
    • souvent, des caractères parasites sont présents

Étape 5 : je légende mon document « tableau de suivi », selon mon code couleurs

Étape 6 : je trie et chiffre le travail effectué

Étape 7 : je reporte les informations dans le « tableau de bord » (le récit au jour le jour de mon travail, pour l’ABES et pour moi) et dans le document « Suivi pour info réseau » (les infos sur l’avancée du chantier, pour les membres du réseau).

Dans le SIGB Horizon, la mise à jour du catalogue local s’effectue au fil des corrections, par le transfert régulier quotidien.

Les moyens

Outil collaboratif et référent :

Le répertoire BOUDA (GED de l’ABES), un temps utilisé, puis le GoogleDrive permettent un accès garanti aux outils de suivi. Merci à l’ABES de les avoir mis à disposition.

Outils « maison » :

Pour gagner du temps, je me suis créé des « messages-modèles », à destination du guichet d’assistance ABESstp, des Correspondants Catalogage et Autorité de mon établissement, de mon interlocutrice chez Cairn. Je n’ai plus qu’à y remplacer les PPN et/ou URL.

Les difficultés :

  1. L’engagement dans le temps : seule sur la gestion de ce chantier, et occupée comme tout un chacun par les tâches quotidiennes et les autres projets de mon établissement, je n’ai pas pu respecter le délai imparti. De plus, l’accord initial ne prévoyant pas un travail si poussé sur les notices, l’estimation du temps de traitement s’est vite avérée complètement fausse.
  2. Les créations d’APP : elles peuvent s’avérer difficiles, si ni IdRef ni l’ouvrage lui-même ne fournissent d’information sur l’auteur. La zone 340 de l’autorité ne peut donc être renseignée.

Conclusion

Bilan quantitatif

C’est là où le bât blesse : surprises au gré du chantier, suivi du chantier en solitaire, charge de travail, … La quantité de notices traitées est loin de celle visée. Le traitement est long. En cette fin d’ année universitaire 2015-2016, 493 notices sont traitées selon les modalités approfondies, pour 814 liens en 7XX et 56 créations d’APP.

Bilan qualitatif

  1. La qualité du Sudoc : à propos du travail effectué, je suis plutôt satisfaite. Une satisfaction à la fois personnelle, parce que le format des notices d’e-books, nouveau à mes yeux n’a plus de secret pour moi, et aussi professionnelle, de par la contribution à l’enrichissement de ces notices, et ceci non seulement pour mon établissement, mais à l’échelle du réseau (ndlr : depuis avril 2016, la BNU de Strasbourg s’est aussi lancée dans un chantier CERCLES sur les monographies encyclopédiques CAIRN).
  2. La qualité des notices fournies par l’éditeur : mon interlocutrice chez Cairn compile les types de problèmes rencontrés, et veille à l’amélioration future de la fourniture des métadonnées, afin de ne pas reproduire ces problèmes désormais identifiés.

L’ABES et moi

cercles_rond

Mon référent est toujours disponible. Merci à Kattialyn G. et aussi à Laurent P. ! J’ai été très honorée que l’ABES m’ait proposé ce projet. Je me sens d’autant plus active au sein du réseau que mon établissement participe à un chantier de mutualisation d’enrichissement des données.

La valorisation et la visibilité des données n’est pas une mince affaire, mais à l’heure de l’évolution des catalogues de bibliothèques, une collaboration entre les éditeurs et l’ABES, mise en pratique par les membres du réseau, est capitale.

Aurélie Bec, pour le SCD de l’université de Picardie Jules Verne  logo_scd_upjv