Open pigreco opened 1 year ago
Caro @pigreco, non riesco a fare "spiegoni". Ma provo a iniziare con qualche esempio.
Il punto di partenza è avere uno strumento per esplorare il file. Va bene un buon editor di testo, capace di mappare la struttura.
Io uso la riga di comando, con gli strumenti di base per il testo (head, tail, grep, ...) e jq e soprattutto (per esplorare) fx.
Esplorando il tuo file, si vede che a primo livello gerarchico c'è una proprietà di tuo interesse relationships
.
Se la vogliamo estrarre, con la gran parte dei tool, basterà scrivere .relationships
, che in qualche modo vuol dire "a partire dalla radice, estrai relationships
. In jq quindi è
<relazioni.json jq '.relationships'
In output l'elenco di tutte le relazioni:
Ogni relazione è un a chiave, a cui è associato - dopo i :
- un valore. Il valore non è in questo caso una semplice stringa, ma un oggetto JSON, composto da altre coppie chiave valore.
In jq, puoi avere l'elenco delle chiavi di relationships
con <relazioni.json jq '.relationships|keys'
.
Se vuoi esplorare una specifica key, dell'oggetto relationship, quindi ad esempio la relazione REL_AB_CDA_AB_CDA_AB_CDA_SUP
<relazioni.json jq '.relationships.REL_AB_CDA_AB_CDA_AB_CDA_SUP'
{
"type": "Association",
"related_table_type": "feature",
"cardinality": "OneToOne",
"left_table_name": "AB_CDA",
"right_table_name": "AB_CDA_AB_CDA_SUP",
"left_table_fields": [
"ClassID"
],
"right_table_fields": [
"ClassREF"
],
"forward_path_label": "Attributi da AB_CDA_AB_CDA_SUP",
"backward_path_label": "Attributi da AB_CDA"
}
E dentro questo oggetto trovi coppie chiave valore semplici, e chiave che contengono un array. L'array si riconosce dalle parentesi quadre. Sopra, ad esempio, è right_table_fields
. Anche se è un solo valore, è mappato come array, perché potenzialmente può essere composto da più valori.
Se vuoi recuperare il primo valore di array di right_table_fields
<relazioni.json jq '.relationships.REL_AB_CDA_AB_CDA_AB_CDA_SUP.right_table_fields[0]'
Con 0
si indica il primo, perché sono "zero based".
Per estrarre soltanto le relazioni, o altri oggetti, si tratta soltanto di comprendere come può essere fatta la struttura di un json, con oggetti, chiavi, valori, array, ecc. e scegliere uno strumento per fare query di estrazione/trasformazione.
Io spesso faccio tutto (anche per pigrizia) con la coppia jq, miller. Ma l'ideale è fare tutto con uno strumento.
Miller, e molti altri programmi per lettura e trasformazione di dati, preferiscono avere oggetti elaborabili linea per linea. E per questo, anche per ragioni di performance, esiste il formato JSON Lines, in cui ogni linea è un singolo oggetto JSON valido.
Quindi invece di avere un contenitore con N oggetti dentro
si estraggono i singoli oggetti, e ogni linea è come se fosse il contenuto di un singolo file JSON.
{"type":"Association","related_table_type":"feature","cardinality":"OneToOne","left_table_name":"AB_CDA","right_table_name":"AB_CDA_AB_CDA_SUP","left_table_fields":["ClassID"],"right_table_fields":["ClassREF"],"forward_path_label":"Attributi da AB_CDA_AB_CDA_SUP","backward_path_label":"Attributi da AB_CDA"}
{"type":"Association","related_table_type":"feature","cardinality":"OneToOne","left_table_name":"AB_CDA","right_table_name":"AB_CDA_AB_CDA_SUP_L","left_table_fields":["ClassID"],"right_table_fields":["ClassREF"],"forward_path_label":"Attributi da AB_CDA_AB_CDA_SUP_L","backward_path_label":"Attributi da AB_CDA"}
{"type":"Association","related_table_type":"feature","cardinality":"OneToOne","left_table_name":"AB_CDA","right_table_name":"AB_CDA_AB_CDA_SUP_SG","left_table_fields":["ClassID"],"right_table_fields":["ClassREF"],"forward_path_label":"Attributi da AB_CDA_AB_CDA_SUP_SG","backward_path_label":"Attributi da AB_CDA"}
Con jq, si ottiene con <relazioni.json jq -c '.relationships[]'
. Aggiungendo []
fa in modo di rimuovere il contenuto di relationships
dalle {}
e con -c
hai tutto compattato in singole righe.
Questo formato, è "masticabile" nativamente da Miller, visidata, ecc..
Con visidata è
<relazioni.json jq -c '.relationships[]' | vd -f jsonl
Con Miller
<relazioni.json jq -c '.relationships[]' | mlr --j2c unsparsify
Per il momento mi fermo qui.
Bellissima spiegazione, unica cosa che non capisco e che se lancio
<relazioni.json jq -c '.relationships[]' | vd -f jsonl
ottengo:
quindi uso:
<relazioni.json jq -c '.relationships[]' | mlr --j2c unsparsify | vd -f csv
per ottenere:
Ciao @pigreco Miller e VisiData sono due programmi distinti e ognuno ha delle scelte diverse sui dati di input.
Per i JSON, vd di default non espande le colonne che sono array e che potenzialmente possono avere quindi valori multipli.
Però una volta aperto il flusso JSON, puoi espandere la singola colonna, tutte le colonne, ecc..
Dopo che lo apri in vd, dai ad esempio il comando g(
per espandere tutte le colonne (qui la documentazione).
Aggiungo un po' di teoria:
JSON prende origine dalla sintassi degli oggetti letterali in JavaScript. Un oggetto letterale può essere definito così:
var JSON = {
proprieta1: 'Valore',
proprieta2: 'Valore',
proprietaN: 'Valore'
}
Si tratta di coppie di proprietà/valori
separate dalla virgola ad eccezione dell'ultima. L'intero oggetto viene racchiuso tra parentesi graffe. A differenza di questa notazione JavaScript, che può contenere anche funzioni e valori complessi, JSON ammette solo valori semplici ed atomici, tra cui:
link utili:
Un JSON può essere:
Una raccolta di coppie nome-valore: Il nome deve essere una stringa tra virgolette; e il valore può essere un altro string, un array, un numero, boolean o nullo. Il valore stesso può essere un altro JSON object.
Una raccolta ordinata: JSON può essere utilizzato per archiviare una raccolta ordinata di oggetti/valori. La raccolta è simile a un array di primitive e array di oggetti nei linguaggi di programmazione.
Ho questo file json (relazioni)
il mio interesse è nell'estrarre i dati presenti nei vari oggetti con struttura diversa e creare file csv:
per esempio
layers
ha questa struttura:in questo caso come estrarre, per ogni layer, tutte le sue proprietà e renderle disponibili in formato csv?
domains
ha questa struttura:in questo caso come estrarre, per ogni layer, tutte le sue proprietà e renderle disponibili in formato csv?
relationships
ha questa struttura:in questo caso come estrarre, per ogni layer, tutte le sue proprietà e renderle disponibili in formato csv?
a me interessa estrarre, per ogni
keys
, tutti i suoi oggetti e allinearli in un csv; sotto un esempio di outputrelazioni.zip