{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "Inizio radunando tutti gli **IMPORT** necessari per girare il notebook, per chiarezza." ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "# IMPORT ESSENZIALI\n", "\n", "# Per il parsing dell'XML -- questo pacchetto è incluso anche nel più generale lxml\n", "import xml.etree.ElementTree as ET\n", "# Utilities per leggere/scrivere files csv\n", "import csv\n", "# Utilities per gestire i character encodings\n", "import unicodedata\n", "# Dizionari ordinati\n", "from collections import OrderedDict\n", "\n", "\n", "# IMPORT OPZIONALI\n", "\n", "# Per fare un stima della velocità delle varie istruzioni\n", "from datetime import datetime\n", "# Generatore di numeri casuali -- può sempre servire in fase di testing\n", "from random import *\n", "# Può servire per alcuni test\n", "import sys\n", "# Per le regex\n", "import re" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# FUNZIONI\n", "\n", "**ElementTree** ha una funzione built-in, **iter**, che scorre (molto velocemente) su tutti i 'nodi' dell'albero di dati che rappresenta l'XML. La funzione *iter* purtroppo però non traccia i nodi 'parents'.\n", "\n", "Ho esteso quindi la libreria scrivendo una mia versione di *iter*, **'traceElems'**, che dovrebbe riuscire a fornirci tutto quello di cui abbiamo bisogno.\n", "\n", "*traceElems* traccia tutti i nodi nell'albero tenendo conto dei 'parents', e restituisce tutti quelli per cui la funzione-argomento 'condition' ritorna True. **NON** indaga i nodi **figli** di quelli che sono restituiti." ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "# La funzione BASE: traceElems\n", "def traceElems(node: ET.Element, condition, parents: list = [], coords: list = []):\n", " res = []\n", " jj = 0\n", " for child in node:\n", " if condition(child):\n", " res.append({'a_par': parents+[node],\n", " 'coords': coords+[jj], 'child': child})\n", " else:\n", " res = res + traceElems(child, condition, parents+[node], coords+[jj])\n", " jj = jj+1 \n", " return res\n", "\n", "# Funzione-base per stoppare traceElems\n", "def isLeafOrC(aa: ET.Element):\n", " if(aa.tag=='c' or len(aa)==0):\n", " return True\n", " else:\n", " return False" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "# Funzioni-utilità che servono solo a visualizzare meglio i dati sul notebook.\n", "def shownode(node: ET.Element):\n", " return (node.tag, node.attrib, node.text.replace('\\t','').replace('n','').strip() \\\n", " if type(node.text) is str else '')\n", "\n", "def shownodelist(el: ET.Element):\n", " return list(map(shownode, el))\n", "\n", "\n", "# Utility copiata da INTERNEZZ -- versione 'multipla' del metodo str.index:\n", "def indices(lst, element):\n", " result = []\n", " offset = -1\n", " while True:\n", " try:\n", " offset = lst.index(element, offset+1)\n", " except ValueError:\n", " return result\n", " result.append(offset)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# AL LAVORO" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**DA CAMBIARE A SECONDA DEL COMPUTER**: directory di input e output" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [], "source": [ "import_dir = '/Users/federicaspinelli/TEAMOVI/Parser/DATA/ASPO/XML/'\n", "export_dir = '/Users/federicaspinelli/TEAMOVI/Parser/DATA/ASPO/DATE/CORRETTE/'" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Importo il file XML del Datini, tracciando il tempo necessario" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0.1180269718170166\n" ] } ], "source": [ "ts1 = datetime.timestamp(datetime.now())\n", "\n", "treeDatini = ET.parse(import_dir + 'export_aspoGT001--gettatelli.xml')\n", "rootDatini = treeDatini.getroot()\n", "\n", "ts2 = datetime.timestamp(datetime.now())\n", "print(ts2 - ts1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Uso *iter* per trovare tutti i nodi con label **'c'** nel file Datini, e mi faccio restituire il\n", "valore dell'attributo **'level'**; salvo tutti i *levels* nella variabile **cLevs**" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'fonds', 'item'}\n" ] } ], "source": [ "cLevs = set(map(lambda a : a.attrib['level'], rootDatini.iter('c')))\n", "print(cLevs)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A questo punto metto al lavoro la funzione **traceElems**: registro TUTTI i nodi **'c'** dividendoli in base all'attributo **'level'**; mi faccio stampare il numero di elementi per ogni livello ed il tempo trascorso.\n", "\n", "**OCCHIO:** per come è costruita, questa routine non va ad investigare dentro i livelli restituiti -- quindi si perde eventuali sotto-livelli con la stessa label di quelli che trova durante il primo scan. La presenza di sotto-livelli di questo tipo va controllata separatamente." ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "# di tag \"c\", livello fonds, primo passaggio: 1\n", "# di tag \"c\", livello item, primo passaggio: 685\n", "\n", "Tempo trascorso: 0.002321958541870117\n" ] } ], "source": [ "ts1 = datetime.timestamp(datetime.now())\n", "\n", "allCs = {}\n", "\n", "for label in cLevs:\n", " def tempFilt(aa: ET.Element):\n", " if(aa.tag=='c' and aa.attrib['level']==label):\n", " return True\n", " else:\n", " return False\n", " \n", " allCs[label] = traceElems(rootDatini, tempFilt);\n", " print('# di tag \"c\", livello ' + label + ', primo passaggio:', len(allCs[label]))\n", "\n", "print()\n", "print('Tempo trascorso:', datetime.timestamp(datetime.now()) - ts1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Notare che l'elaborazione è piuttosto veloce (sul mio laptop) malgrado la dimensione del file.\n", "\n", "Rimane il problema dei livelli dentro a livelli omonimi. Vediamo di affrontarlo." ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "# di tag \"c\", livello fonds, primo passaggio: 1\n", "# di tag \"c\", livello fonds, totali: 1\n", "# di tag \"c\", livello item, primo passaggio: 685\n", "# di tag \"c\", livello item, totali: 685\n", "\n", "Tempo trascorso: 0.04202413558959961\n" ] } ], "source": [ "ts1 = datetime.timestamp(datetime.now())\n", "\n", "allCs2 = {}\n", "\n", "for label in cLevs:\n", " partial = allCs[label]\n", " print('# di tag \"c\", livello ' + label + ', primo passaggio:', len(partial))\n", " allCs2[label] = partial\n", " partialUpdate = []\n", " while True:\n", " def tempFilt(aa: ET.Element):\n", " if(aa.tag=='c' and aa.attrib['level']==label):\n", " return True\n", " else:\n", " return False\n", " for node in partial:\n", " partialUpdate = partialUpdate + traceElems(node['child'], tempFilt)\n", " #print(len(partialUpdate))\n", " partial = partialUpdate\n", " if(len(partialUpdate)==0):\n", " break\n", " allCs2[label] = allCs2[label] + partial\n", " partialUpdate = []\n", "\n", " print('# di tag \"c\", livello ' + label + ', totali:', len(allCs2[label]))\n", "\n", "print()\n", "print('Tempo trascorso:', datetime.timestamp(datetime.now()) - ts1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A questo punto diventa facile visualizzare tutti i dettagli dei vari elementi **'c'**, di qualunque livello; un esempio è fornito nella prossima cella. Si può cambiare l'elemento da visualizzare cambiando il valore delle variabili *ii* e *level*" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "item: 25\n", "['c', 'did', 'materialspec']\n", "[{'level': 'item', 'id': 'IT-ASPO-GT001-0000026', 'audience': 'external'}, {}, {'label': 'tipologia'}]\n", "['', '', 'scheda anagrafica']\n", "\n", "['c', 'did', 'repository']\n", "[{'level': 'item', 'id': 'IT-ASPO-GT001-0000026', 'audience': 'external'}, {}, {}]\n", "['', '', 'Archivio di Stato di Prato']\n", "\n", "['c', 'did', 'unitid', 'extref']\n", "[{'level': 'item', 'id': 'IT-ASPO-GT001-0000026', 'audience': 'external'}, {}, {'countrycode': 'IT', 'encodinganalog': 'ISAD 1 - 1 reference code', 'repositorycode': 'ASPO'}, {'role': 'id_galileo'}]\n", "['', '', '', 'A46C062A-DC08-4F95-B54E-69E48DDE7AEB']\n", "\n", "['c', 'did', 'unitid', 'emph']\n", "[{'level': 'item', 'id': 'IT-ASPO-GT001-0000026', 'audience': 'external'}, {}, {'countrycode': 'IT', 'encodinganalog': 'ISAD 1 - 1 reference code', 'repositorycode': 'ASPO'}, {'altrender': 'numero provvisorio'}]\n", "['', '', '', '10']\n", "\n", "['c', 'did', 'container']\n", "[{'level': 'item', 'id': 'IT-ASPO-GT001-0000026', 'audience': 'external'}, {}, {'type': 'registro'}]\n", "['', '', 'VV']\n", "\n", "['c', 'did', 'unittitle', 'persname', 'emph']\n", "[{'level': 'item', 'id': 'IT-ASPO-GT001-0000026', 'audience': 'external'}, {}, {'encodinganalog': 'ISAD 1 - 2 title'}, {'role': 'bambino'}, {'altrender': 'nome'}]\n", "['', '', '', '', 'Perla Maria']\n", "\n", "['c', 'did', 'unittitle', 'num']\n", "[{'level': 'item', 'id': 'IT-ASPO-GT001-0000026', 'audience': 'external'}, {}, {'encodinganalog': 'ISAD 1 - 2 title'}, {'type': 'matricola'}]\n", "['', '', '', '287']\n", "\n", "['c', 'did', 'unittitle', 'date']\n", "[{'level': 'item', 'id': 'IT-ASPO-GT001-0000026', 'audience': 'external'}, {}, {'encodinganalog': 'ISAD 1 - 2 title'}, {'type': 'ritrovamento', 'normal': '17820401-17820401'}]\n", "['', '', '', '01/04/1782']\n", "\n", "['c', 'did', 'unittitle', 'unitdate', 'emph']\n", "[{'level': 'item', 'id': 'IT-ASPO-GT001-0000026', 'audience': 'external'}, {}, {'encodinganalog': 'ISAD 1 - 2 title'}, {'normal': '17820401-17820401'}, {}]\n", "['', '', '', '', 'ritrovamento: 01/04/1782']\n", "\n", "['c', 'did', 'physdesc', 'physfacet']\n", "[{'level': 'item', 'id': 'IT-ASPO-GT001-0000026', 'audience': 'external'}, {}, {'encodinganalog': 'ISAD 1 - 5 extent and medium of the unit of description'}, {'type': 'descrizione contrassegno'}]\n", "['', '', '', 'Nastro in seta gialla con mezzo soldo in rame.']\n", "\n", "['c', 'note', 'p']\n", "[{'level': 'item', 'id': 'IT-ASPO-GT001-0000026', 'audience': 'external'}, {'encodinganalog': 'ISAD 6 - 1 note'}, {}]\n", "['', '', 'Nota dell\\'ospedale: \"Si battezzi la bambina di nascita [venuta] per la nostra ferrata alle ore sei incirca della scorsa sera per mano di Rosa vedova di Francesco Galantini di questa citt� quale asser� essere di genitori incerti e del distretto Pistoiese; detta bambina aveva pendente dal collo con un nastro giallo di seta un mezzo soldo di nostra moneta; fu [ricevuta] e mandata al sacro fonte col nome Perla Maria\".\\tSul medesimo biglietto, in calce: \"Ad� 23 aprile 1782. La suddetta bambina consegnata alla Maria Anna di Francesco Toccafondi di S. Lionardo a Vernio\".']\n", "\n", "['c', 'daogrp', 'daoloc']\n", "[{'level': 'item', 'id': 'IT-ASPO-GT001-0000026', 'audience': 'external'}, {}, {'href': '/GETTATELLI/010_a.jpg', 'title': '010_a.JPG'}]\n", "['', '', 'None']\n", "\n", "['c', 'daogrp', 'daoloc']\n", "[{'level': 'item', 'id': 'IT-ASPO-GT001-0000026', 'audience': 'external'}, {}, {'href': '/GETTATELLI/010_a.JPG_1', 'title': '010_a.JPG_1'}]\n", "['', '', 'None']\n", "\n", "['c', 'daogrp', 'daoloc']\n", "[{'level': 'item', 'id': 'IT-ASPO-GT001-0000026', 'audience': 'external'}, {}, {'href': '/GETTATELLI/010_b.jpg', 'title': '010_b.JPG'}]\n", "['', '', 'None']\n", "\n", "['c', 'daogrp', 'daoloc']\n", "[{'level': 'item', 'id': 'IT-ASPO-GT001-0000026', 'audience': 'external'}, {}, {'href': '/GETTATELLI/010_c.JPG_1', 'title': '010_c.JPG_1'}]\n", "['', '', 'None']\n", "\n", "['c', 'daogrp', 'daoloc']\n", "[{'level': 'item', 'id': 'IT-ASPO-GT001-0000026', 'audience': 'external'}, {}, {'href': '/GETTATELLI/010_c.jpg', 'title': '010_c.JPG'}]\n", "['', '', 'None']\n", "\n", "['c', 'processinfo', 'list', 'item', 'date']\n", "[{'level': 'item', 'id': 'IT-ASPO-GT001-0000026', 'audience': 'external'}, {}, {}, {}, {}]\n", "['', '', '', '', '04-2014']\n", "\n", "['c', 'processinfo', 'list', 'item', 'persname']\n", "[{'level': 'item', 'id': 'IT-ASPO-GT001-0000026', 'audience': 'external'}, {}, {}, {}, {}]\n", "['', '', '', '', 'regesta.exe']\n", "\n" ] } ], "source": [ "level = 'item'\n", "ii = 25\n", "test = allCs2[level][ii]\n", "\n", "print(level+':',ii)\n", "\n", "toProc = traceElems(test['child'], isLeafOrC)\n", "for node in toProc:\n", " tags = list(map(lambda a: a.tag, node['a_par'])) + [node['child'].tag]\n", " attributes = list(map(lambda a: a.attrib, node['a_par'])) + [node['child'].attrib]\n", " contents = list(map(lambda a: a.text.replace('\\n','').replace('\\n','').strip(), node['a_par'])) + [str(node['child'].text).replace('\\n','').replace('\\n','').strip()]\n", "\n", " print(tags)\n", " print(attributes) \n", " print(contents)\n", " print()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A questo punto, quello che devo fare è scrivere un **traduttore** -- una funzione che scorra l'output degli elementi esaminati e trasformi le info in modo da poterle esportare in formato csv (o in qualunque altro formato vogliamo).\n", "\n", "La mia attuale versione di **traduttore per gli item** è data nella prossima cella; accetta come argomento un nodo (che è supposto essere di tipo item) e restituisce un dict." ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [], "source": [ "def traduttoreItem(elem):\n", " # Variabile che contiene l'output della traduzione:\n", " csvProt = {}\n", "\n", " # Processo i nodi-parent di 'elem'\n", " par_tags = list(map(lambda a: a.tag, elem['a_par']))\n", " par_attributes = list(map(lambda a: a.attrib, elem['a_par']))\n", " # e0: Le varie id dei nodi parent\n", " for ii in indices(par_tags, 'c'):\n", " key = 'id_' + par_attributes[ii]['level']\n", " csvProt[key] = par_attributes[ii]['id']\n", "\n", " # Processo i nodi-child di 'elem'\n", " toProc = traceElems(elem['child'], isLeafOrC)\n", " first = True\n", " for node in toProc:\n", " tags = list(map(lambda a: a.tag, node['a_par'])) + [node['child'].tag]\n", " attributes = list(map(lambda a: a.attrib, node['a_par'])) + [node['child'].attrib]\n", " content = node['child'].text\n", "\n", " # Da controllare solo per il primo nodo\n", " # (informazioni a livello del nodo, uguali per tutti i figli)\n", " if(first):\n", " # e1 ID della item\n", " csvProt['id'] = attributes[tags.index('c')]['id']\n", " # e2 Audience: external o internal\n", " try:\n", " csvProt['audience'] = attributes[tags.index('c')]['audience']\n", " except:\n", " pass\n", " # e19 Otherlevel\n", " try:\n", " csvProt['altro_livello'] = attributes[tags.index('c')]['otherlevel']\n", " except:\n", " pass\n", " first = False\n", "\n", " # La 'ciccia': si processa il contenuto vero e proprio\n", "\n", " if('unittitle' in tags):\n", " try:\n", " ii = tags.index('unitdate')\n", " try:\n", " norm = attributes[ii]['normal']\n", " csvProt['data_periodo_normalizzata'] = norm\n", " csvProt['data_periodo'] = content\n", " except:\n", " csvProt['data_periodo_normalizzata'] = 'NOTNORMAL'\n", " except:\n", " pass \n", " \n", " # e11: Il titolo da unittitle\n", " try:\n", " aa = csvProt['titolo_aspo']\n", " except:\n", " try:\n", " ii = tags.index('unittitle')\n", " try:\n", " csvProt['titolo_aspo'] = str(node['a_par'][ii].text).replace('\\t','').replace('\\n','').strip()\n", " except:\n", " csvProt['titolo_aspo'] = str(content).replace('\\t','').replace('\\n','').strip()\n", " except:\n", " pass\n", " # e10 Repository (qui dovrebbe essere sempre l'Archivio di Prato)\n", " if('repository' in tags):\n", " csvProt['repository'] = content\n", "\n", " # e4 Tipologia\n", " try:\n", " ii = tags.index('materialspec')\n", " if(attributes[ii]['label']=='tipologia'): \n", " csvProt['tipologia'] = content\n", " except:\n", " pass\n", "\n", " # e1 Persona + ruolo\n", " try:\n", " ii = tags.index('emph')\n", " type1 = attributes[ii]['altrender']\n", " if(type1=='cognome'):\n", " csvProt['cognome_bambino'] = content\n", " if(type1=='nome'):\n", " csvProt['nome_bambino'] = content\n", " except:\n", " pass\n", "\n", " # e2 Matricola\n", " try:\n", " ii = tags.index('num')\n", " type1 = attributes[ii]['type']\n", " if(type1=='matricola'):\n", " csvProt['matricola'] = content\n", " except:\n", " pass\n", " \n", " # e6 Registri Gettatelli\n", " try:\n", " ii = tags.index('container')\n", " type1 = attributes[ii]['type']\n", " if(type1=='registro'):\n", " csvProt['riferimento_registro'] = content\n", " except:\n", " pass\n", "\n", " #e7 Id oggetto nella scatola\n", " try:\n", " aa = csvProt['id_oggetto']\n", " except:\n", " try:\n", " ii = tags.index('unitid')\n", " try:\n", " for chi in node['a_par'][ii]:\n", " tails = \"\" + chi.tail\n", " csvProt['id_oggetto'] = (node['a_par'][ii].text + tails).replace('\\t','').replace('\\n','').strip()\n", " except:\n", " pass\n", " except:\n", " pass\n", " \n", " # e2 Date varie: tutte quelle con 'type' definito\n", " try:\n", " ii = tags.index('date')\n", " key = 'data_' + attributes[ii]['type']\n", " aa = csvProt[key]\n", " except:\n", " try:\n", " ii = tags.index('date')\n", " try:\n", " csvProt[key] = str(node['a_par'][ii].text).replace('\\t','').replace('\\n','').strip()\n", " try:\n", " ii = tags.index('emph')\n", " csvProt[key+'_note'] = content\n", " except:\n", " pass\n", " try:\n", " ii = tags.index('date')\n", " key = 'data_' + attributes[ii]['type'] + '_normalizzata'\n", " try:\n", " norm = attributes[ii]['normal']\n", " csvProt[key] = norm\n", " except:\n", " csvProt[key] = 'NOTNORMAL'\n", " except:\n", " pass\n", " except:\n", " csvProt[key] = str(content).replace('\\t','').replace('\\n','').strip()\n", " try:\n", " ii = tags.index('date')\n", " key = 'data_' + attributes[ii]['type'] + '_normalizzata'\n", " try:\n", " norm = attributes[ii]['normal']\n", " csvProt[key] = norm\n", " except:\n", " csvProt[key] = 'NOTNORMAL'\n", " except:\n", " pass\n", " except:\n", " pass\n", "\n", " # e3 Data 1: periodo\n", "\n", " # e1 Scope-content head & body\n", " if('scopecontent' in tags):\n", " if('head' in tags):\n", " csvProt['scope-content_head'] = content\n", " else:\n", " if('p' in tags):\n", " csvProt['scope-content_body'] = content\n", "\n", " # e8 Supporto fisico\n", " try:\n", " ii = tags.index('physfacet')\n", " if(attributes[ii]['type']=='descrizione contrassegno'):\n", " csvProt['descrizione_contrassegno'] = content\n", " if(attributes[ii]['type']=='conservazione'):\n", " csvProt['conservazione'] = content\n", " except:\n", " pass\n", "\n", " # e11 Note\n", " if('note' in tags):\n", " csvProt['nota'] = content\n", " \n", " # e13 Oggetto digitale allegato (nome)\n", " # Questo è un campo multiplo; per il momento, salviamo tutto\n", " # su una cella concatenando e separando i campi con una pipe\n", " # '| '\n", " try:\n", " ii = tags.index('daoloc')\n", " out = attributes[ii]['title']\n", " try:\n", " csvProt['oggetto_digitale'] = csvProt['oggetto_digitale'] + ' | ' + out\n", " except:\n", " csvProt['oggetto_digitale'] = out\n", " except:\n", " pass \n", " \n", " return csvProt\n", "\n", "\n", "# Di pari passo alla funzione, definisco un dict contenente tutti gli header;\n", "# servirà per il CSV.\n", "itemHeader = OrderedDict()\n", "\n", "# e1 ID dell'entità\n", "itemHeader.update({'id': ''})\n", "\n", "# e2 Audience: external o internal\n", "itemHeader.update({'audience': ''})\n", "\n", "# e15 Repository (qui dovrebbe essere sempre l'Archivio di Prato)\n", "itemHeader.update({'repository': '#'})\n", "\n", "# e10 Tipologia\n", "itemHeader.update({'tipologia': '#'})\n", "\n", "# e11 Persona + ruolo\n", "itemHeader.update(\n", "{'cognome_bambino': '#', 'nome_bambino': '#',})\n", "\n", "# e17 Segnatura codice\n", "itemHeader.update({'matricola': '#'})\n", "\n", "# e12 Registri Gettatelli\n", "itemHeader.update(\n", "{'riferimento_registro':'#'})\n", "\n", "# e7 ID oggetto\n", "itemHeader.update({'id_oggetto': '#'})\n", "\n", "# e8 Date varie: tutte quelle con 'type' definito\n", "itemHeader.update(\n", "{'data_ritrovamento': '#', 'data_ritrovamento_normalizzata': '#',\n", " 'data_nascita': '#', 'data_nascita_normalizzata': '#',\n", " 'data_morte': '#', 'data_morte_normalizzata': '#',\n", " 'data_ricongiungimento': '#', 'data_ricongiungimento_normalizzata': '#',\n", " 'data_adozione': '#', 'data_adozione_normalizzata': '#'})\n", "\n", "# e4 Titolo ASPO\n", "itemHeader.update({'titolo_aspo': '#'})\n", "\n", "# e18 Data 1: periodo\n", "itemHeader.update({'data_periodo': '#' , 'data_periodo_note': '#', 'data_periodo_normalizzata': '#' })\n", "\n", "# e14 Supporto fisico\n", "itemHeader.update({'descrizione_contrassegno': '#', 'conservazione': '#' })\n", "\n", "# e3 Scope content, head & body\n", "itemHeader.update(\n", "{'scope-content_head': '#',\n", " 'scope-content_body': '

#'})\n", "\n", "# Note\n", "itemHeader.update({'nota': '#'})\n", "\n", "# e18 Oggetto digitale allegato (nome)\n", "itemHeader.update({'oggetto_digitale': ''})\n", "\n", "#0: Le varie id dei nodi parent\n", "itemHeader.update(\n", "{'id_subfonds': '',\n", " 'id_fonds': '',\n", " 'id_series': '',\n", " 'id_subseries': '',\n", " 'id_file': '',\n", " 'id_otherlevel': '',\n", " 'id_collection': ''})" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Test della funzione traduttore\n", "\n", "**NB:** l'ho definita basandomi sugli item, ma sembra funzionare decentemente anche sugli altri livelli!" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "id_fonds: 04-2014\n", "\n", "id: IT-ASPO-GT001-0000002\n", "\n", "audience: external\n", "\n", "tipologia: scheda anagrafica\n", "\n", "repository: Archivio di Stato di Prato\n", "\n", "id_oggetto: 2\n", "\n", "riferimento_registro: SS\n", "\n", "titolo_aspo: \n", "\n", "nome_bambino: Potidio\n", "\n", "matricola: 112\n", "\n", "data_periodo_normalizzata: 17620101-17621231\n", "\n", "data_periodo: 1762\n", "\n", "descrizione_contrassegno: Cordoncino con due brevi in stoffa verde con nappe multicolore e con medaglia rettangolare contenente un disegno della Madonna con bambino.\n", "\n", "oggetto_digitale: 484_a.JPG\n", "\n" ] } ], "source": [ "test = allCs2['item'][1]\n", "toShow = traduttoreItem(test)\n", "for key in toShow.keys():\n", " print(key + ': ' + str(toShow[key]))\n", " print()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Export\n", "\n", "Produciamo il CSV per gli item tracciando, al solito, il tempo impiegato." ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Tempo trascorso: 0.18084406852722168\n" ] } ], "source": [ "# Do it! Export del CSV - items.\n", "\n", "ts1 = datetime.timestamp(datetime.now())\n", "\n", "# Apro il file per l'export\n", "with open(export_dir + \"data_item.csv\", \"w\", newline=\"\") as csv_file:\n", " # Definisco la classe-motore per l'export\n", " writer = csv.DictWriter(csv_file, fieldnames=list(itemHeader.keys()))\n", " # Scrivo l'intestazione\n", " writer.writeheader()\n", " # Scrivo la seconda riga, esplicativa\n", " writer.writerow(itemHeader)\n", " # Scrivo gli item tradotti, uno a uno\n", " for ii in range(len(allCs2['item'])):\n", " test = allCs2['item'][ii]\n", " writer.writerow(traduttoreItem(test))\n", "\n", "print('Tempo trascorso:', datetime.timestamp(datetime.now()) - ts1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Altri livelli" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Definisco un dizionario ridotto per l'header delle *subseries*, poi esporto -- per il momento con lo stesso traduttore usato per gli *item*" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "*Rinse & Repeat* con i livelli *series*, *subfonds* e *fonds*" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Tempo trascorso: 0.02116990089416504\n" ] } ], "source": [ "ts1 = datetime.timestamp(datetime.now())\n", "\n", "fondsKeys = set()\n", "for ii in range(len(allCs2['fonds'])):\n", " test = allCs2['fonds'][ii]\n", " fondsKeys = fondsKeys.union( traduttoreItem(test).keys() )\n", "\n", "fondsHeader = OrderedDict()\n", "for key in itemHeader:\n", " if(key in fondsKeys):\n", " fondsHeader[key] = itemHeader[key]\n", "\n", "\n", "with open(export_dir + \"data_fonds.csv\", \"w\", newline=\"\") as csv_file:\n", " writer = csv.DictWriter(csv_file, fieldnames=list(fondsHeader.keys()))\n", " writer.writeheader()\n", " writer.writerow(fondsHeader)\n", " for ii in range(len(allCs2['fonds'])):\n", " test = allCs2['fonds'][ii]\n", " writer.writerow(traduttoreItem(test))\n", "\n", "print('Tempo trascorso:', datetime.timestamp(datetime.now()) - ts1)" ] } ], "metadata": { "interpreter": { "hash": "397704579725e15f5c7cb49fe5f0341eb7531c82d19f2c29d197e8b64ab5776b" }, "kernelspec": { "display_name": "Python 3.9.0 64-bit", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.0" }, "metadata": { "interpreter": { "hash": "31f2aee4e71d21fbe5cf8b01ff0e069b9275f58929596ceb00d14d90e3e16cd6" } } }, "nbformat": 4, "nbformat_minor": 2 }