Open BNI

Il 30 maggio 2016 viene annunciato il rilascio libero della Bibliografia Nazionale Italiana (BNI). Viene apprezzata l'apertura di questo catalogo (anche se con i limiti dei soli pdf), e da profano di biblioteconomia faccio anche una domanda sull'effettivo caso d'uso della BNI.
Il 30 agosto 2016 viene annunciato il rilascio delle annate 2015 e 2016 anche in formato UNIMARC e MARCXML.
Incuriosito dal catalogo inizio ad esplorarlo, per pensare a possibili trasformazioni (triple rdf) o arricchimenti con/verso altri dati (wikidata).

Ecco come esplorare i dati con basex e xquery e un notebook jupyter:

  • download degli xml (mi limito all'analisi delle monografie):
~ curl -OJLs "http://bni.bncf.firenze.sbn.it/bniweb/scaricaxml.jsp?mese=01&anno=2015&serie=Monografie"
~ curl -OJLs "http://bni.bncf.firenze.sbn.it/bniweb/scaricaxml.jsp?mese=02&anno=2015&serie=Monografie"
~ curl -OJLs "http://bni.bncf.firenze.sbn.it/bniweb/scaricaxml.jsp?mese=03&anno=2015&serie=Monografie"
~ curl -OJLs "http://bni.bncf.firenze.sbn.it/bniweb/scaricaxml.jsp?mese=01&anno=2016&serie=Monografie"

~ sha1sum Monografie*.xml
7c226c88daefd7b145ebb0bc01d621ba9f3ea9b3  Monografie201501.xml
204134fef0f5275f466feb9c6a018c794fadd07b  Monografie201502.xml
bdbcab246290b9d2e0db3b7279bd32ea20ea6ef3  Monografie201503.xml
c8e56442bc5c8a1e7fb9e31731108ba586993c17  Monografie201601.xml

debian/ubuntu: ~ apt-get install basex
macos: ~ brew install basex

  • creazione del database e caricamento degli xml
~ basex -c "create database bni"
~ basex -i bni -c "add Monografie201501.xml; add Monografie201502.xml;\
                   add Monografie201503.xml; Monografie201601.xml"
  • avvio del db
~ basexserver
  • installazione di jupyter notebook e della libreria client in python per basex
~ pip3 install jupyter
~ pip3 install basexclient
~ jupyter notebook

In nuovo notebook si possono quindi iniziare ad estrarre i dati con xquery. Esempio di una semplice funzione che conta le occorrenze di un path (xpath):

from BaseXClient import BaseXClient

session = BaseXClient.Session('127.0.0.1', 1984, 'admin', 'admin')

publisher = '//rec/df[@t="210"]/sf[@c="c"]'
publisher_city = '//rec/df[@t="210"]/sf[@c="a"]'
subject = '//rec/df[@t="606"]/sf[@c="a"]'

def count(path, limit):
    q = '''let $db := db:open("bni")
    let $result :=
        for $publisher in distinct-values($db{0})
              let $count :=  count(index-of($db{0}, $publisher))
              order by $count descending
        return concat($publisher, ", ", $count)
    for $limited at $lim in subsequence($result, 1, {1})          
        return $limited'''.format(path, limit)
    query = session.query(q)
    for _, item in query.iter():
        print(item)

I 10 editori e le città con maggior numero di pubblicazioni:

count(publisher, 10)
count(publisher_city, 10)

oppure i 30 soggetti piu' usati (field 606)

count(subject, 30)

Il notebook già pronto può essere scaricato da atomotic/bni-xquery

Conclusioni

Cosa fare con questi dati? Sicuramente arricchire wikidata, ad esempio ci sono pochissimi item di editori italiani.

La BNI può essere considerato un primo passo verso l'apertura completa del catalogo OPAC? Speriamo di si.