Sei sulla pagina 1di 37

Università degli Studi di Trieste

Facoltà di Ingegneria

Corso di Laurea Triennale di Ingegneria Informatica

TESI DI LAUREA TRIENNALE IN “SISTEMI INFORMATIVI”

SVILUPPO DI UNA APPLICAZIONE PER


L’ACQUISIZIONE DI DATI DA SUPPORTO
CARTACEO: CASO DEI CURRICULUM VITAE

Relatore: Laureando:
Prof. Fermeglia Maurizio Faelli Roberto

Anno Accademico 2008/2009


Sommario

1 - INTRODUZIONE...........................................................................................................................3
2 – ANALISI........................................................................................................................................5
2.1 – Analisi del sistema...................................................................................................................6
2.1.1 – Il progetto.........................................................................................................................6
2.1.2 – Utenza...............................................................................................................................6
2.1.3 – L’ambiente di sviluppo.....................................................................................................7
2.1.4 – Definizione dei requisiti...................................................................................................7
2.2 – Progettazione del sistema........................................................................................................9
2.2.1 – L’architettura....................................................................................................................9
2.2.2 – Use Case Diagram..........................................................................................................11
2.2.4 – Activity diagram.............................................................................................................12
2.2.5 – Class diagram.................................................................................................................13
3 - REALIZZAZIONE.......................................................................................................................15
3.1 Implementazione......................................................................................................................16
3.1.1 Visual Studio.....................................................................................................................16
3.1.2 Le novità del .NET Framework 3.5...................................................................................17
3.1.3 Linguaggio Visual C#........................................................................................................18
3.1.4 XPS (XML Paper Specification).......................................................................................19
3.1.5 Interfaccia grafica..............................................................................................................21
3.1.6 Esempio di utilizzo............................................................................................................23
3.1.7 Esempi di codice C#..........................................................................................................27
4 - CONCLUSIONI............................................................................................................................34
5 - RINGRAZIAMENTI....................................................................................................................35

2
1 - INTRODUZIONE
In questa tesi si vuole descrivere la progettazione e lo sviluppo di una applicazione che
permetta di acquisire dati da supporto cartaceo ed in particolare si concentra
sull’acquisizione dei dati relativi ai curriculum vitae in formato Europeo.
Lo scopo del progetto, in sintesi, è quello di creare un applicativo che, permetta di effettuare
la scansione di un curriculum vitae esistente (tipicamente in formato PDF oppure DOC)
convertirlo nel formato XPS, effettuare un mappaggio dei valori letti durante la scansione in
una opportuna struttura ed esplicitare i parametri che permettono di migliorare la qualità
dell’interpretazione.
Uno degli obiettivi fondamentali che il laureando si è posto è stato quello di creare
un’applicazione che risulti essere il più possibile “user-friendly” ma nello stesso tempo
completa di tutte le funzionalità (modelli di acquisizione, parametri definibili dall’utente,
anteprima del documento, acquisizione da più fonti…) necessarie a questo tipo di lavoro.

Per realizzare l’applicazione è stato utilizzato il linguaggio di programmazione C#


all’interno dell’ambiente di sviluppo Visual Studio 2008 Professional.

Le fasi principali che hanno portato allo sviluppo del programma si possono riassumere
brevemente nei seguenti punti:

 • Analisi delle esigenze da risolvere;


 • Valutazione delle tecnologie disponibili;
 • Studio di realtà già esistenti;
 • Raccolta dei requisiti per la progettazione dell’applicazione;
 • Progettazione architetturale;
 • Implementazione e realizzazione dell’applicazione;
 • Test del prototipo;

La seguente tesi si suddivide in due sezioni principali.

3
Nella prima parte verrà illustrata l’analisi e la progettazione del sistema da realizzare. In
particolare saranno esposte alcune considerazioni sui documenti di tipo XPS (di cui
parleremo approfonditamente nelle prossime pagine)
Si procederà poi con la raccolta delle informazioni, con la stesura dei requisiti ed infine si
passerà alla progettazione vera e propria attraverso i diagrammi UML.

Nella seconda parte verrà trattata la realizzazione del programma. Si inizierà con una
descrizione dettagliata della sua implementazione mediante il linguaggio C# e si passerà poi
ad una illustrazione del suo funzionamento.

La tesi termina con un sezione dedicata alle conclusioni in cui si riassume lo stato attuale del
progetto: descrive in particolare cosa, per ora, è stato fatto e cosa c’è ancora da fare per
rendere il prodotto più completo e funzionale.

4
2 – ANALISI
In questa prima parte del documento viene presentata un’analisi del sistema che si andrà a
realizzare. Si inizierà da un resoconto di quelle che sono le necessità che l’applicativo
dovrà risolvere, per arrivare poi alla individuazione dei requisiti del sistema. Una volta
determinati tali requisiti si passerà alla stesura della progettazione, nella quale verranno
illustrati l’architettura di riferimento e alcuni diagrammi UML.

5
2.1 – Analisi del sistema

2.1.1 – Il progetto

Come già anticipato nell’introduzione, il progetto richiede la costruzione di una


applicazione Windows Form che permetta l’acquisizione di curriculum vitae (di seguito CV)
pervenuti in formato cartaceo oppure mediante posta elettronica.

Nel caso in cui il CV sia in formato cartaceo, l’utente effettuerà la scansione del documento
per poi salvarlo in una opportuna cartella. In seguito si procederà alla ricostruzione del CV
(in una apposita struttura) grazie alle funzionalità presenti nel programma.
Nel caso il CV pervenga mediante posta elettronica, il programma offrirà all’utente la
possibilità di accedere ai messaggi presenti nella mailbox e di ricostruire l’eventuale CV
allegato (come nel caso precedente).
Ad acquisizione completata, il CV sarà disponibile nel nuovo formato XML (eXtensible
Markup Language) per ulteriori utilizzi futuri (da definire con l’utente finale in quanto
dipende dal gestionale utilizzato…).

2.1.2 – Utenza

L’utilizzo del programma non implica alcuna difficoltà per cui può essere utilizzato anche
da persone che presentano conoscenze elementari di informatica (concetto di file,
cartella…). In una prima fase, si dovrà semplicemente informare il software quale sarà la
cartella contenente i CV da acquisire. I parametri di acquisizione sono già ottimizzati per il
CV in formato Europeo. L’operatore può comunque in ogni istante variare tali parametri e
verificarne in tempo reale l’efficacia. Se le modifiche sono soddisfacenti, è possibile
salvarle e utilizzarle successivamente. Al momento, il programma salva il CV nella stessa
cartella di origine (nulla vieta che in una prossima release venga chiesto all’operatore in
quale altro percorso salvare…).

6
2.1.3 – L’ambiente di sviluppo

Per sviluppare l’applicazione è stato utilizzato L’IDE Microsoft Visual Studio 2008 e il
linguaggio di programmazione C# (C Sharp).

In particolare, all’interno del programma, si sono utilizzati i namespaces


System.Windows.Xps al fine di mettere a disposizione delle classi in grado di
leggere/scrivere documenti XPS nonché i namespaces System.Xml per fornire supporto
all'elaborazione dei files XML.

Da quanto detto, è evidente che i curriculum vitae prima di essere manipolati dal
programma, devono essere prima di tutto trasformati da supporto cartaceo a supporto
digitale ed in particolare devono essere convertiti in formato XPS. Il programma, infatti,
permette di convertire formati di CV diversi (ad esempio .DOC, .PDF, .RTF) in formato
XPS grazie all’OCR engine della OmniPage (API – Application Program Interface messe a
disposizione del programmatore).

2.1.4 – Definizione dei requisiti

A seguito delle considerazioni fatte nei paragrafi precedenti, è possibile stendere un elenco
dei requisiti a cui il software dovrà far fronte.

Requisiti funzionali:
 Source selector:
l’applicazione deve poter acquisire documenti (CV) da più sorgenti distinte. Nel caso
specifico, sono state individuate due sorgenti:
 Cartella presente nel file system (definibile all’interno del programma)
 Casella di posta (i messaggi che contengono allegati…)
 Source content:
all’interno dell’applicazione deve essere presente un listato all’interno del quale l’utente
potrà trovare tutti i files dei CV da convertire
 Selected document:
l’utente deve essere in grado di effettuare una anteprima del CV originale prima di
procedere alla conversione

7
 Scan current:
il software deve essere in grado di acquisire CV con formati diversi ad esempio .DOC,
.RTF, .XPS e quindi effettuarne il parsing in una nuova struttura di tipo XPS
 View scan result:
l’utente deve essere in grado di visualizzare il CV ricostruito in una apposita finestra
 Action panel:
L’utente deve essere in grado di correggere i parametri relativi alla scansione e quindi di
ritentare l’operazione (salvando eventualmente i parametri modificati)
 L’applicazione, al termine dell’acquisizione, deve salvare il nuovo CV in formato .XML
 Edit parameters:
Tutti i parametri contenuti nell’applicativo devono essere facilmente modificabili e salvati in
modo persistente su file.

8
2.2 – Progettazione del sistema
2.2.1 – L’architettura

L’architettura di un prodotto software rappresenta il modo con cui vengono organizzate ed


interfacciate le varie componenti che andranno a formare il sistema finale.

Nel caso del programma realizzato, ci troviamo nella programmazione di Windows Forms
mediante linguaggio C#.

Lo schema che meglio rappresenta l’architettura del software è presente in figura 1. Si tratta
dell'architettura .NET Framework. Nei prossimi paragrafi andremo ad analizzare i vari strati
che compongono tale framework.

Figura 1 – architettura .NET Framework

Common Language Specification (CLS)


Il CLS è una serie di regole che si applicano per generare gli assembly. Se un componente
scritto in un linguaggio (ad esempio C#) dovrà essere utilizzato da un altro linguaggio (ad
esempio VB.NET), allora chi scrive il componente dovrà aderire ai tipi e alle strutture
definite dal CLS.

Ad esempio, il tipo Int32 è compatibile con il CLS ed i linguaggi e gli strumenti possono
aspettarsi che altri linguaggi e strumenti conformi al CLS sappiano come utilizzarlo
correttamente.

9
Una libreria costituita da codice aderente al CLS è chiamata "CLS Framework". Queste
librerie sono progettate per essere utilizzate da un gran numero di linguaggi e strumenti di
sviluppo.

Windows Forms
Microsoft Windows Forms è il nome dato alla parte di GUI (Graphical User Interface) del
framework Microsoft .NET.
Microsoft Windows Forms è visto come un sostituto per il precedente e più complesso
sistema Microsoft Foundation Classes basato su C++.

.NET Framework Base Classes


Le classi del .NET Framework costituiscono un insieme di librerie di classe (API) unificato,
orientato all'oggetto, gerarchico ed estensibile che gli sviluppatori possono utilizzare dai
linguaggi che già conoscono.
Attualmente, chi programma in Visual C++ utilizza le Microsoft Foundation Classes, gli
sviluppatori Visual J++ adoperano le Windows Foundation Classes, mentre coloro che
scrivono in Visual Basic sfruttano il runtime di Visual Basic stesso. In poche parole, le
classi del .NET Framework unificano questi approcci differenti, dando vita ad un
sovrainsieme di tutte le varie funzionalità. Di conseguenza, non è più necessario conoscere
diversi modelli ad oggetti o librerie di classe. Creando un unico insieme di API comune a
tutti i linguaggi di programmazione, il .NET Framework consente l'ereditarietà, la gestione
degli errori ed il debug tra linguaggi. In altre parole, tutti i linguaggi di programmazione, da
JScript a C++, diventano uguali, e gli sviluppatori sono liberi di scegliere quello più adatto
alle proprie necessità.
Il .NET Framework fornisce classi che possono essere invocate da qualsiasi linguaggio di
programmazione. Tali classi si conformano ad un insieme di criteri di nomenclatura e di
progettazione che riducono ulteriormente la curva di apprendimento degli sviluppatori.

Common Language Runtime (CLR)


Il Common Language Runtime rappresenta un motore di esecuzione ad elevate prestazioni.
Il codice cui il runtime si riferisce e la cui esecuzione è gestita da esso viene detto codice
gestito (managed code). La responsabilità per attività quali la creazione di oggetti,
l'esecuzione di chiamate a metodi e così via, è demandata al Common Language Runtime
che consente di fornire servizi aggiuntivi al codice in esecuzione.
A dispetto del suo nome, il Common Language Runtime riveste in realtà un ruolo tanto nella
fase di sviluppo di componenti quanto nella fase di esecuzione.

Mentre la componente è in esecuzione, il runtime fornisce servizi quali la gestione della


memoria (inclusa la garbage collection), la gestione di processi e thread, il potenziamento
della sicurezza e si preoccupa di soddisfare le eventuali dipendenze da altre componenti.

Durante la fase di sviluppo, il ruolo del runtime cambia leggermente. Grazie agli
automatismi introdotti (ad esempio nella gestione della memoria), il runtime rende la vita
dello sviluppatore molto più semplice. In particolare, caratteristiche quali la gestione del
ciclo di vita, una nomenclatura forte dei tipi, la gestione delle eccezioni tra linguaggi, la
gestione degli eventi basati sui delegate, il binding dinamico e la reflection, riducono
considerevolmente la quantità di codice che occorre scrivere per realizzare codice a
componenti riutilizzabili.

10
I runtime non rappresentano una novità per i linguaggi: molti linguaggi di programmazione
possiedono un runtime. Visual Basic, ad esempio, possiede forse il runtime più famoso (il
VBRUN), ma anche Visual C++ ne possiede uno (MSVCRT) e così pure Visual FoxPro,
Jscript, SmallTalk, Perl, Python, Haskell e Java. Il ruolo critico del Common Language
Runtime, e ciò che realmente lo contraddistingue, è il fatto che fornisce un ambiente di
runtime unificato comune a tutti i linguaggi di programmazione.
Le caratteristiche fondamentali del runtime includono un sistema comune di tipi che
consente l'integrazione tra linguaggi (oggetti C# possono ereditare classi C++, ad esempio) ,
componenti autodescrittive, un deployment più semplice ed un miglior controllo dei conflitti
di versione ed infine, servizi di sicurezza integrati.

2.2.2 – Use Case Diagram


Dall’elenco dei requisiti illustrati nel paragrafo 2.1.4 è possibile ricavare direttamente i casi
d’uso dell’applicazione. Di seguito viene visualizzato il diagramma dei casi d’uso, il quale
permette allo sviluppatore di avere una visione d’insieme del sistema che si stà analizzando.

Figura 2 – Use Case diagram

11
L’attore del sistema è unico e coincide con l’utente finale che svolge le funzioni di
caricamento e conversione dei CV.

2.2.4 – Activity diagram


L’activity diagram riportato in Figura 3 mostra la sequenza di operazioni che devono essere
effettuate al fine di convertire un CV dal formato originale (ad es. PDF) verso il nuovo
formato XML.

Figura 3 – Activity diagram

12
2.2.5 – Class diagram

Il diagramma delle classi descrive il sistema generale, la sua struttura statica, ovvero la sua
modellizzazione in classi. È composto dai seguenti elementi:

Classi
Una classe è caratterizzata da un nome e descrive le proprietà comuni ad un gruppo di
oggetti. Una classe può essere completata con la lista di attributi e operazioni che contiene.
È un rettangolo composto da tre parti: il nome della classe in grassetto, la lista di attributi e
la lista di operazioni. Il nome della classe è obbligatorio mentre le due parti sottostanti
possono essere tralasciate.

Attributi
Un attributo è un elemento della classe che contiene un valore. L'attributo deve essere unico
solo nella classe, quindi due classi possono avere attributi identificati dallo stesso nome. Un
attributo può contenere un valore costante oppure può essere modificato da delle operazioni.
Un attributo può contenere solo dei valori e non degli oggetti: esso rappresenta infatti una
proprietà dell'entità reale. Esso non dovrebbe essere un identificatore univoco creato per
distinguere due istanze. Se l'attributo rappresenta un identificatore reale, quale ad esempio il
codice fiscale, esso può essere utilizzato anche per distinguere due oggetti.

Operazioni
Un'operazione è un'azione o una trasformazione che può essere applicata da o su un oggetto
in una classe. Tutti gli oggetti di una classe condividono le stesse operazioni.
Argomenti impliciti di un'operazione sono l'oggetto su cui si applica che è l'oggetto stesso e
l'azione effettuata, che può dipendere dalla particolare implementazione. Gli argomenti
espliciti sono opzionali e devono avere un tipo. Essi sono indicati in una lista separati da
virgole. Un'operazione ha un tipo di ritorno, che è opzionale nel caso in cui l'operazione non
ritorni alcun valore.

13
Figura 4 - Class Diagram

14
3 - REALIZZAZIONE
In questa seconda unità del documento viene presentata la fase di implementazione della
Windows-Application.
Si partirà da una breve illustrazione delle particolari caratteristiche dell’ambiente di
sviluppo seguita da un tutorial sull’utilizzo del programma.
Il capitolo quindi termina proponendo alcuni spezzoni di codice C# che costituiscono
l’ossatura del software in oggetto..

15
3.1 Implementazione

3.1.1 Visual Studio

L’intero applicativo è stato sviluppato all’interno dell’ambiente Visual Studio 2008


edizione Professional.

Visual Studio 2008 e il .NET Framework 3.5 aggiungono tante nuove caratteristiche ad un
ambiente di lavoro già molto ricco ed avanzato, con l’obiettivo di incrementare
ulteriormente i livelli di produttività degli sviluppatori.

Una delle più apprezzate caratteristiche del nuovo Visual Studio è la possibilità di
selezionare la versione del .NET Framework con cui lavorare: molto spesso, infatti, capita
di dover intervenire su applicazioni sviluppate con versioni diverse del .NET Framework e
sarebbe piuttosto scomodo dover installare sulla propria macchina diverse versioni di
Visual Studio. Per tale motivo Visual Studio 2008 consente di scegliere quale versione del
Framework utilizzare di volta in volta.
Scegliendo la versione appropriata del Framework vengono impostati automaticamente i
toolbox, i tipi di progetto, i riferimenti e tutto il resto.

Figura 5 – scelta versione framework

16
Si può anche decidere di convertire un’applicazione in una versione differente del .NET
Framework.

Se si utilizza Visual Studio 2008 per aprire un’applicazione sviluppata con una versione
precedente del Framework viene automaticamente proposto l’aggiornamento della stessa
all’ultima versione disponibile, per consentirvi di utilizzare le nuove caratteristiche
dell’ambiente e continuare ad utilizzare applicazioni sviluppate con una versione
precedente del .NET Framework.

Come per l’edizione 2005, esistono diverse versioni di Visual Studio 2008, ciascuna mirata
a ben precise esigenze.

Express Edition - Questa versione è gratuita, liberamente scaricabile e rivolta a coloro che
si avvicinano per la prima volta a questo mondo, a chi lo fa per hobby, agli studenti, a tutti
coloro che vogliono scrivere codice liberamente e senza particolari pretese. Questa è la
risposta di Microsoft agli strumenti freeware disponibili oggi per gli sviluppatori.
Chiaramente questa edizione non presenta tutte le funzionalità delle corrispondenti versioni
a pagamento, tuttavia contiene tutti gli strumenti necessari e sufficienti per creare
applicazioni client/server, siti web e web service.

Standard Edition - Questa versione rappresenta la base di partenza per gli sviluppatori
professionisti. Essa è simile alla Express ma mette a disposizione degli sviluppatori tutti i
linguaggi .NET ed un insieme maggiore di caratteristiche e funzionalità tra cui: supporto
alle soluzioni multiprogetto, Windows Communication Foundation (WCF), Windows
Workflow (WF), tool di distribuzione Click-Once, SQL Server 2005 Express incluso,
compatibilità con Visual Source Safe e molto altro.

Professional Edition - La differenza fondamentale tra la versione Standard e la


Professional è l’insieme più esteso di caratteristiche e funzionalità che la seconda possiede
rispetto alla prima. Tra di esse bisogna citare: Visual Studio Tools per Office, SQL Server
2005 Developer Edition, possibilità di sviluppare software per dispositivi mobili, Crystal
Reports, Server Explorer e molto altro. Oltre a queste caratteristiche addizionali la versione
Professional viene venduta insieme a diverse sottoscrizioni MSDN. Può essere acquistata
senza MSDN o con due diverse versioni di MSDN (Professional o Premium). Con la
versione MSDN Professional si acquisisce il diritto di utilizzare le vecchie versioni di
Visual Studio e di utilizzare Visual Source Safe. Si ottengono anche licenze di Windows,
Windows Server, Virtual PC e altre. Con la versione MSDN Premium, oltre a ciò che è
stato elencato in precedenza, si ottengono licenze per SQL Server, licenze per Microsoft
Office Systems 2007 e altre.

3.1.2 Le novità del .NET Framework 3.5

Il .NET Framework 2.0 ha introdotto diverse classi base, interfacce, generics e altro. Il
.NET Framework 3.0 ha introdotto elementi come Windows Presentation Foundation
(WPF), Windows Communication Foundation (WCF) e Windows Workflow Foundation

17
(WF). L’ultima versione del Framework (la 3.5 appunto) include LINQ, una revision di
ASP.NET e molto altro.
Chiaramente non è possibile in questa sede analizzare tutte le nuove caratteristiche, tuttavia
possiamo evidenziare alcune delle novità più importanti:

ASP.NET – Il .NET Framework include diversi miglioramenti e novità per gli sviluppatori
web. Il namespace System.Web include nuove classi e controlli ed il Framework supporta
direttamente la programmazione con AJAX. Tra le altre cose vi sono un nuovo controllo
per la visualizzazione dei dati, chiamato ListView, ed un nuovo oggetto, chiamato
LinqDataSource, per lavorare con dati LINQ.

LINQ – Il namespace System.Linq definisce gli operatori ed i tipi LINQ standard. Il


namespace System.Data.Linq provvede alle connessioni tra i database e i sottosistemi
LINQ. Da citare anche altri namespace molto utili: System.Data.Linq.Mapping,
System.Xml.Linq. Molti dei controlli del Framework sono stati aggiornati per lavorare con
LINQ.

Windows Communication Foundation (WCF) – Il nuovo System.ServiceModel


incapsula quello che è conosciuto come WCF. Con questa funzionalità è possibile creare
facilmente applicazioni basate su servizi che operano su diversi protocolli.

Windows Presentation Foundation (WPF) – WPF fornisce una nuova tecnologia di


presentazione per le applicazioni Windows.

Windows Workflow Foundation (WF) - WF permette di creare per le vostre applicazioni


flussi di lavoro sequenziali e guidati dagli stati. Esso è inoltre integrato con WCF, quindi si
può facilmente esporre e richiamare un flusso di lavoro come servizio WCF.

Supporto a Windows Vista – Il motore Windows Form è stato aggiornato per rendere le
applicazioni compatibili con Windows Vista. Ciò significa che aggiornando le vostre
vecchie applicazioni darete ad esse l’aspetto di applicazioni per Vista e potrete utilizzare
tutte le finestre di dialogo in stile Vista.

.NET Compact Framework – Il Framework 3.5 fornisce una nuova versione del Compact
Framework. Esso può essere utilizzato per dispositivi mobili come Smartphone e
dispositivi WindowsMobile\CE.

3.1.3 Linguaggio Visual C#

L’applicativo è stato scritto utilizzando il linguaggio C# presente in Visual Studio 2008.


Propongo ora una velocissima panoramica che riguarda proprio C#.
Visual C# è basato sulla solida eredità di C++. Immediatamente familiare agli sviluppatori
C++ e Java, C# è un linguaggio di programmazione moderno e intuitivo orientato agli
oggetti che offre miglioramenti significativi, inclusi un sistema di tipi unificato, il codice di

18
tipo unsafe per conferire agli sviluppatori il massimo controllo e nuovi costrutti potenti e
facilmente comprensibili dalla maggior parte degli sviluppatori.

Gli sviluppatori hanno a disposizione un linguaggio innovativo orientato ai componenti,


con un supporto intrinseco per proprietà, indexer, delegati, gestione delle versioni, overload
degli operatori e attributi personalizzati. Con i commenti XML gli sviluppatori in C# hanno
la possibilità di documentare il codice sorgente in modo significativo e utile. Un modello di
ereditarietà avanzato consente inoltre agli sviluppatori di riutilizzare il codice scritto in
qualsiasi linguaggio di programmazione che supporti .NET.
Gli sviluppatori C# possono unirsi a una community di sviluppatori in rapidissima crescita
e in quell'ambito scambiare codice e risorse, sfruttare competenze acquisite in diversi
ambienti informatici e contribuire al processo di standardizzazione che garantisce la
partecipazione attiva alla community.

3.1.4 XPS (XML Paper Specification)

In una prima fase, il programma accetta un CV (tipicamente in formato PDF oppure DOC)
e lo converte nel formato XPS per poi analizzarne il contenuto.
E’ chiaro, quindi, che è necessario fornire al lettore una panoramica riguardante proprio
tale nuovo formato.

Con Windows Vista Microsoft ha introdotto un nuovo formato per l'interscambio di file tra
gli utenti, un formato che, come Office OpenXML è bastato sulle specifiche XML. Stiamo
parlando di XPS, un nuovo formato che permette di salvare documenti da qualsiasi
programma e di leggerli da un reader.

Cosa sono i documenti XPS

XPS abbreviazione di XML Paper Specification, è il formato che Microsoft ha creato


durante lo sviluppo di Windows Vista e del .NET Framework 3.0. Conosciuto
precedentemente con il nome di "Metro", XPS è un contenitore basato sullo standard di
compressione ZIP, con all'interno alcuni file xml e binari che sono visibili semplicemente
cambiando l'estensione del file da XPS a ZIP.

I file XPS consentono di essere condivisi tra gli utenti, possono essere creati facilmente da
qualsiasi programma, utilizzando Microsoft XPS Document Writer, e mantengono la
formattazione dell'originale.

XPS sfrutta Windows Presentation Foundation il sottosistema grafico sviluppato per


Windows Vista: in questo modo ci si vuole assicurare che il "rendering" dei file in questo
formato sia effettuato nella stessa maniera su qualunque periferica di stampa. E' considerato
come il concorrente di Adobe PDF dato che può risultare utile per distribuire documenti (e
renderne possibile la visualizzazione in modo univoco e conforme all'originale) anche alle
persone non dotate dell'applicazione con cui il file è stato generato, per creare documenti
multipagina a partire da contenuti (come può essere una lunga pagina web) non suddivisi

19
per pagine, per archiviare testi ed elaborati con un formato prefissato e comodo da
visionare.

Come crearli

I documenti in formato XPS sono realizzabili a partire da qualsiasi programma, se


utilizzate Microsoft Office 2007, esiste il comando che permette la creazione di XPS
(stessa procedura per la creazione di un PDF).

Salvare documenti XPS da altri programmi, invece, si può fare utilizzando il driver di
stampa Microsoft XPS Document Writer, gli utenti di Windows Vista non dovranno
installare nulla perché già dispongono di tutte le tecnologie necessarie per la realizzazione
dei file XPS. Gli utenti di Windows XP e Windows Server 2003 dovranno installare
Microsoft .NET Framework 3.0 e Microsoft XPS Essentials Pack, disponibili
gratuitamente sul sito di Microsoft.
Per realizzare un documento XPS si dovrà solamente attivare nella finestra stampa di un
qualsiasi programma, la stampante virtuale denominata Microsoft XPS Document Writer,
successivamente basta fare clic su OK o su Stampa, a seconda del programma utilizzato, e
decidere il nome e la posizione del file XPS nella finestra di dialogo Salva il file come.

Come aprirli

I documenti XPS sono al momento visibili solo da Windows Vista, Windows XP e


Windows Server 2003, attraverso Internet Explorer 7, come per realizzarli, anche per
leggerli su Windows XP e Windows Server 2003, è necessario che siano installati
Microsoft .NET Framework 3.0 e Microsoft XPS Essentials Pack visti in precedenza.

20
3.1.5 Interfaccia grafica

Se prendiamo come riferimento una delle tante definizioni di interfaccia grafica presenti su
Internet, ad esempio:

“L'interfaccia utente grafica, in sigla GUI (graphical user interface), è un paradigma di


sviluppo che mira a consentire all'utente di interagire con il computer manipolando
graficamente degli oggetti, svincolandolo dall'obbligo di imparare una serie di comandi da
impartire con la tastiera come invece avviene con le più tradizionali interfacce testuali CLI
(command line interface). È lo strato di un'applicazione software che si occupa del dialogo
con l'utente del sistema utilizzando un ambiente grafico.”

Anche nello sviluppo di questo programma si è cercato di aderire il più possibile a tali
principi.
Andiamo ora a vedere le sezioni principali presenti nella form dell’applicativo:
Source
Settings
selector

Source Selected Rebuilded


content document document

Figura 6 - interfaccia grafica

21
Una attenzione particolare verso due pulsanti di comando fondamentali per l’intera
applicazione:

Figura 7 - scansione e visualizzazione

Scansione documento corrente: fa partire la procedura di acquisizione in due step:

 se il file non è nel formato XPS allora lancia una procedura che trasformerà il file in
un XPS
 se il file è già un XPS allora segue il normale flusso predisposto

Visualizza risultato scansione: visualizza il file XML generato grazie al pulsante visto
precedentemente nel rebuilded panel.

Da notare, inoltre, la possibilità per l’utente di creare, modificare ed eliminare diversi


modelli di acquisizione del CV. In sostanza, l’operatore è libero di correggere i parametri
di scansione e ritentare l’operazione per ottenere un risultato finale migliore.
Nelle seguenti figure alcuni esempi:

Figura 8 - scelta modello di scansione

Figura 9 - finestra gestione modelli di scansione

22
3.1.6 Esempio di utilizzo

Vediamo ora quali sono le azioni che l’utente dovrà compiere al fine di ottenere
l’acquisizione di un curriculum vitae. Verso la fine di questo capitolo verrà visualizzato
come modificare le impostazioni del programma al fine di cambiare il path dei documenti,
il numero dei messaggi da visualizzare, il modello di acquisizione ecc.

Selezione del CV da cartella presente nel file system

Il programma presenta l’elenco dei CV presenti nella cartella. E’ possibile eseguire una
preview di uno di loro facendo doppio clic sul CV che si intende acquisire.

Figura 10 - selezione CV

Selezione del CV da un allegato presente nella Inbox dell’utente

L’utente sceglie il messaggio che contiene come allegato il CV e opera un semplice doppio
clic.

Figura 11 - scelta messaggio con allegato

Verrà proposto dove salvare l’allegato contenente il CV

Figura 12 - scelta cartella per salvataggio allegato

23
Conferma dell’avvenuto salvataggio.

Figura 13 - conferma salvataggio allegato

A questo punto, l’utente potrà selezionare il CV come visto precedentemente.

Anteprima del documento

Una volta deciso quale sia il CV da acquisire, con un doppio clic è possibile ottenerne una
anteprima.

Figura 14 - preview del CV da acquisire

Acquisizione

Grazie al pulsante “Scansione documento corrente” sarà possibile convertire il CV dal suo
formato originale nel nuovo formato XPS e quindi gestire la scansione mediante appositi
parametri a disposizione dell’utente.
Notare come la scansione venga eseguita seguendo i parametri di default.

24
Nelle immagini seguenti alcuni screenshots

Figura 15 - pulsante avvio scansione e scelta modello di scansione

Visualizzazione risultato finale

Dopo aver acquisito il CV, è possibile verificare la qualità dell’operazione facendo clic sul
pulsante “Visualizza risultato scansione”.

Figura 16 - pulsante per la visualizzazione CV dopo l'acquisizione

Il CV acquisito è stato trasformato in una apposita struttura che suddivide le etichette dai
dati veri e propri. L’utente può visualizzare questo facendo clic sugli elementi del CV.
Nell’esempio, si può notare come l’etichetta “Data di nascita” venga contraddistinta
(colorata) in modo diverso dal contenuto del campo stesso che è “01.01.1980” (giallo)

Figura 17 - com'è strutturato il CV al termine dell'acquisizione

Correzione parametri di scansione

Il programma nasce con alcuni modelli di scansione predefiniti ad esempio “Modello 1”,
“Modello 2”. L’utilizzatore può perciò scegliere quale sarà il modello più indicato per il
tipo di documento da acquisire oppure può modificare i parametri di scansione in modo
temporaneo in qualsiasi istante. E’ inoltre libero di eliminare modelli oppure di crearne di
nuovi. La finestra che permette di gestire il tutto è presente in figura X: (raggiungibile
facendo clic sul seguente pulsante:

Figura 18 - gestione dei modelli di scansione

25
Figura 19 - finestra per la gestione dei modelli di scansione

Come si può notare, è possibile modificare i singoli valori relativi ad un modello esistente
oppure creare un nuovo modello e infine, eliminare un modello esistente.

Impostazioni del programma

Chiude la panoramica relativa all’applicativo la sezione dedicata alle impostazioni relative


al programma. La seguente figura visualizza quali sono le modifiche possibili che
interessano l’intero applicativo.

Figura 20 - sezione dedicata alle impostazioni generali del programma

 Path documenti: la cartella nella quale si trovano i CV


 Path allegati: la cartella nella quale verranno salvati i CV pervenuti via e-mail
 Path modelli: dove vengono salvati i modelli di scansione
 Modello predefinito: qual è il modello di scansione preferito
 Visualizza mail: il numero di mail da visualizzare

26
3.1.7 Esempi di codice C#

Come anticipato in precedenza, prima di chiudere il 3° capitolo dedicato


all’implementazione, propongo alcuni spezzoni di codice C# utilizzati nel programma.
Verranno illustrate solo le parti fondamentali che costituiscono l’ossatura del programma
stesso.

Impostazioni iniziali del programma

Non appena il programma viene lanciato, l’utente trova già alcune impostazioni “di
fabbrica” comunque editabili in seguito. La gestione di tale attività è controllata dalla
classe “Settings.cs”. Di seguito un estratto di tale classe:

namespace CVScan {

public class Settings {

private static bool _initialized = false;


private static string _settingsFilename = @"\application.ini";
private static XmlConfigSource _source;
private static string _ApplicationPath = "";

private static string _ApplicationConfigsPath = @"\configs\";


private static string _ApplicationLogsPath = @"\logs\";
private static string _ApplicationModelsPath = @"\models\";
private static string _ApplicationDocsPath = @"docs\";
private static string _ApplicationAttachmentsPath = @"docs\";
private static int _MailMaxFetch = 10;
private static string _ApplicationModelDefault = @"";

static Settings() {
}

public static void Init() {


Init(_settingsFilename);
}

public static void Init(string filename) {


Init(filename, "");
}

public static void Init(string filename, string path) {


if(_initialized) {
return;
}
_settingsFilename = filename;

if(path.Length > 0) {
_ApplicationPath = path;
} else {
string appPath =
System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeB
ase);
if(appPath.StartsWith(@"file:\")) {
appPath = appPath.Remove(0, 6);
}
_ApplicationPath = appPath;

27
}
string settingsPath = IOPath.getRootedPath(_settingsFilename,
_ApplicationPath);

if(!File.Exists(settingsPath)) {
_source = new XmlConfigSource();
_source.Save(settingsPath);
}

_source = new XmlConfigSource(settingsPath);

_source.Alias.AddAlias("True", true);
_source.Alias.AddAlias("False", false);

if(_source.Configs.Count == 0) {
_source.AddConfig("Main");
Save();
}
Load();

_initialized = true;
}

Figura 21 - classe per la gestione impostazioni programma

Scansione del documento originale

L’utente ha scelto qual è il CV da sottoporre a scansione dall’apposita listbox, ha già


ottenuto una anteprima del documento e quindi vuole trasformarlo in una apposita struttura
finale. Per ottenere tutto ciò, il programma utilizza più classi che collaborano assieme.
Propongo di seguito una immagine chiarificatrice:

Figura 22 - classi utilizzate per la scansione

La prima classe ad essere utilizzata è: File2XPSOmnipageConverter.cs. Lo scopo


principale è quello di accettare in ingresso un CV in formato ad esempio PDF oppure DOC
e trasformarlo nel formato XPS (sfruttando l’engine Omnipage). Di seguito propongo il
codice legato a tale classe:

28
public class File2XPSOmnipageConverter
{
public static void Convert(string sourceFilename, string destFilename)
{

EngineClass _engine = new EngineClass();


_engine.Init("Nuance", "OmniPage 16", "", 0, 0);

foreach (string filename in


Directory.GetFiles(Properties.Settings.Default.SourcePath))
{
Document _currentDocument = _engine.Documents.Add();
_currentDocument.RecognitionLanguages[(int)tagLANGUAGES.LANG_ITA].Enabled
= true;
_currentDocument.LoadImage(filename, -1, -1);
_currentDocument.
_currentDocument.Recognize(IproPlus.RUNPAGE.);

_currentDocument.Save(
Path.Combine(
Properties.Settings.Default.DestPath,
Path.GetFileNameWithoutExtension(filename) + ".opd"
));

}
}
}

Figura 23 - classe per la trasformazione in formato XPS

A questo punto, abbiamo a disposizione il CV in formato XPS. Il programma ora dovrà


analizzare il contenuto dell’XPS, cercare di differenziare le etichette dai dati veri e propri,
tener conto delle eventuali modifiche ai parametri di scansione prodotte dall’utente e quindi
salvare il tutto nella nuova struttura in formato XML.
Il tutto viene gestito dalla classe CVPageLexer.cs (che a sua volta si appoggia ad altre
classi quali ad esempio CVToken.cs, CVScanTemplate.cs, ScanEntryComparer.cs ecc.

public class XpsPageLexer: XpsLexer


{
private static string NS = "http://schemas.microsoft.com/xps/2005/06";
private static clsModel _model = null;

private List<XpsToken> _scans = new List<XpsToken>();


//per leggere da una FixedPage...
public static XpsPageLexer Scan(IXpsFixedPageReader pageReader, clsModel model)
{
_model = model;

XpsPageLexer lexer = new XpsPageLexer();

// step 1: collect in sorted way


//recupera le info quali Canvas, Glyphs ecc. ecc. presenti nel documento
XDocument xDoc = XDocument.Load(pageReader.XmlReader);
XElement fixedPage = xDoc.Element(XName.Get("FixedPage", NS));
double pageWidth = double.Parse(fixedPage.Attribute("Width").Value);
double pageHeight = double.Parse(fixedPage.Attribute("Height").Value);

29
foreach (XElement canvas in fixedPage.Elements(XName.Get("Canvas", NS)))
{
string canvasRenderTransformText =
canvas.Attribute("RenderTransform").Value;
string[] canvasRenderTransformTexts =
canvasRenderTransformText.Split(',');
Point p = new Point()
{
X =
Math.Round(double.Parse(canvasRenderTransformTexts[4].Replace(".", ",")), 0),
Y =
Math.Round(double.Parse(canvasRenderTransformTexts[5].Replace(".", ",")), 0)
};

foreach (XElement glyphs in canvas.Elements(XName.Get("Glyphs", NS)))


{
string unicodeString =
glyphs.Attribute(XName.Get("UnicodeString")).Value;
string glyphsRenderTransformText =
glyphs.Attribute("RenderTransform").Value;

// step 1.1: candidate labels and values


if (p.X < _model.SepVert)
{
if (lexer._scans.Count > 0)
{
//supponiamo che siano vicini....a livello di X e Y
string old = lexer._scans[lexer._scans.Count - 1].Text;
double oldX = lexer._scans[lexer._scans.Count -
1].Location.X;
double oldY = lexer._scans[lexer._scans.Count -
1].Location.Y;
if((p.X - oldX) < _model.Dist_X && (p.Y - oldY) <
_model.Dist_Y)
{
XpsToken se = new XpsNonTerminalToken();
lexer._scans[lexer._scans.Count - 1].Text = old +
unicodeString;
}
else
{
XpsToken se = new XpsNonTerminalToken();
se.Text = unicodeString;
se.Location = new Point(p.X - _model.Off_X, p.Y -
_model.Off_Y); // offset to be parametrized
lexer._scans.Add(se);
}
}
else
{
//richiama CVToken.cs...e CVTerminalToken
XpsToken se = new XpsNonTerminalToken();
se.Text = unicodeString;
se.Location = new Point(p.X - 2, p.Y - 2); // offset to be
parametrized
lexer._scans.Add(se);
}

else
{
XpsToken se = new XpsTerminalToken();
se.Text = unicodeString;
se.Location = new Point(p.X + 2, p.Y + 2); // offset to be
parametrized

lexer._scans.Add(se);
}

30
}
}

lexer._i = 0;

lexer._scans.Sort(ScanEntryComparer.Default);

return lexer;
}

private int _i;


private XpsToken _current;

public XpsToken Current


{
get { return _current; }
}

public XpsToken Next()


{
if (_i == _scans.Count)
{
_current = null;
return null;
}

_current = _scans[_i++];

return _current;
}
}
}

Figura 24 - la classe CVPageLexer.cs

Terminata questa fase, otteniamo un nuovo file in formato XML che rappresenta il CV
originale con tutte le informazioni in esso contenute disponibili per ulteriori utilizzi futuri.
In sostanza, il programma è riuscito ad estrarre dal CV originale (ad esempio in formato
PDF) tutte le informazioni che poi andranno a popolare un archivio.
Se andiamo infatti a visualizzare la struttura XML del CV una volta terminata la fase di
scansione, potremmo verificare che i dati contenuti nel CV originale, sono effettivamente
disponibili e analizzabili facilmente da programmi che si occupano di gestire files XML.

<?xml version="1.0" encoding="utf-8" ?>


- <root>
<other name="FORMATO EUROPEO" location="96;88" />
<other name="PER IL CURRICULUM" location="93;112" />
<other name="VITAE" location="208;132" />
- <label name="INFORMAZIONI PERSONALI" location="115;222">
- <label name="Nome" location="227;258">
<value name="Mario Rossi" location="259;263" />
</label>
- <label name="Indirizzo" location="216;281">
<value name="Via Lenta,15" location="259;286" />
</label>
- <label name="Telefono" location="213;305">
<value name="0434 000000" location="259;310" />
</label>
<label name="Fax" location="238;328" />

31
- <label name="E-mail" location="225;352">
<value name="XXX@XXX.it" location="259;357" />
<value name="CXX.it" location="331;357" />
</label>
- <label name="Nazionality" location="202;395">
<value name="italiana" location="259;399" />
</label>
- <label name="Data di nascita" location="184;423">
<value name="01.01.1980" location="259;427" />
</label>
</label>
- <label name="ESPERIENZA LAVORATIVA" location="118;474">
- <label name="•Date (da —a)" location="193;508">
<value name="01.06.1996 a 31.12.2003" location="267;511" />
</label>
- <label name="•Nome e indirizzo del datore di lavoro" location="79;526">
<value name="Wurth s.r.l" location="267;529" />
</label>
- <label name="•Tipo di azienda o settore" location="137;544">
<value name="Azienda commerciale. settore sistemi e prodotti di fissaggio"
location="267;547" />
</label>
- <label name="•Tipo di impiego" location="183;562">
<value name="Ag. Commercio/ Funzionario commerciale" location="301;564" />
</label>
- <label name="•Principali mansioni e responsability" location="86;580">
<value name="vendita" location="302;584" />
</label>
<label name="ESPERIENZA LAVORATIVA" location="118;597" />
- <label name="•Date (da —a)" location="193;631">
<value name="01.01.2004 ad 20.10.2004" location="267;634" />
</label>
- <label name="•Nome e indirizzo del datore di lavoro" location="79;649">
<value name="Dominoni s.r.l" location="267;652" />
</label>
- <label name="•Tipo di azienda o settore" location="137;667">
<value name="Commerciale. Impianti condizionamento aria condizionata autoveicoli"
location="267;670" />
</label>
- <label name="•Tipo di impiego" location="183;685">
<value name="Funzionario commercilae" location="302;688" />
</label>
<label name="•Principali mansioni e responsability" location="86;703" />
<label name="ESPERIENZA LAVORATIVA" location="118;721" />
- <label name="•Date (da —a)" location="193;755">
<value name="21.10.2004 ad oggi" location="267;758" />
</label>
- <label name="•Nome e indirizzo del datore di lavoro" location="79;773">
<value name="Vaillant Saunier Duval italia S.p.a" location="267;775" />
</label>
- <label name="•Tipo di azienda o settore" location="137;791">
<value name="Azienda commerciale. Settore riscaldamento condizionamento" location="267;793"
/>
</label>
- <label name="•Tipo di impiego" location="183;809">
<value name="Funzionario Commerciale." location="302;812" />
</label>
- <label name="•Principali mansioni e responsability" location="86;827">
<value name="Vendita. Responsabile commerciale riscaldamento sulla provincia di Milano"
location="302;831" />
</label>

32
</label>
- <label name="ISTRUZIONE E FORMAZIONE" location="110;859">
<other name="•Date (da —a)" location="185;894" />
<value name="1994" location="294;898" />
<value name="-" location="294;898" />
<value name="1989" location="294;898" />
- <label name="•Nome e tipo di istituto di istruzione" location="82;911">
<value name="Collegio Villoresi San Giuseppe" location="293;916" />
<other name="o formazione" location="193;927" />
</label>
- <label name="•Principali materie / ability" location="127;945">
<value name="Economico Aziendale" location="294;949" />
<other name="professionali oggetto dello studio" location="97;960" />
</label>
- <label name="•Qualifica conseguita" location="150;979">
<value name="Ragioniere" location="294;982" />
</label>
- <label name="•Livello nella classificazione" location="118;996">
<value name="39/60" location="293;1000" />
<other name="nazionale (se pertinente" location="136;1011" />
<value name=")" location="257;1026" />
</label>
</label>
</root>

Figura 25 - file XML risultato della scansione

33
4 - CONCLUSIONI

Penso di poter affermare che l’obiettivo di realizzare una Windows - application, che
consenta all’utente di poter convertire curriculum vitae pervenuti in formato cartaceo
oppure in formati quali PDF, DOC ecc verso un formato che permetta in seguito di poter
recuperare i dati sia stato raggiunto.
L’applicazione si presenta con un’interfaccia semplice ed intuitiva, perciò non richiede da
parte dell’utente un grande sforzo per capire come devono essere utilizzati i vari
componenti e le varie funzionalità che costituiscono l’applicazione.
L’applicazione è naturalmente suscettibile di ulteriori perfezionamenti e dovrebbe essere
ulteriormente testata a fondo con opportuni test cases.
Non è stata inserita la funzionalità che riguarda il “dopo scansione” ovvero come gestire i
files (CV) in formato XML. Questo perché il tutto dipende dal gestionale presente
nell’Azienda dove il programma verrà utilizzato.
Tra gli sviluppi futuri vedo anche la possibilità di estendere il salvataggio di allegati non
solo provenienti dalla mailbox di Outlook aziendale ma anche da caselle di posta di tipo
POP3.
Ovviamente, il programma potrebbe essere anche riprogettato al fine di poterlo
trasformare in una Web – Application e quindi utilizzabile da più persone
contemporaneamente mediante il proprio Web-Browser…dipende sempre dal contesto nel
quale si troverà ad operare…

34
5 - RINGRAZIAMENTI

Ringrazio innanzitutto il Prof. Fermeglia Maurizio per la sua disponibilità umana nei miei
confronti e per avermi assegnato una tesi così interessante e dai contenuti tecnologici
moderni.
Un ringraziamento doveroso verso il Dott. Parenzan Marco che mi ha seguito nella
stesura del programma e mi ha arricchito con i suoi consigli preziosissimi in termini di
Object Oriented Programming.
Non posso naturalmente dimenticare di ringraziare mia moglie Daniela e i figli Nicole e
Manuel per la pazienza dimostrata nel periodo in cui ero occupato con gli studi. Ora
potrò dedicarmi di più a loro…

Roberto

35
Bibliografia

 Beginning C# 2008 From Novice to Professional SECOND EDITION


Christian Gross
APRESS

 Professional Visual Studio® 2008


Nick Randolph
David Gardner
Wiley Publishing, Inc.

 Ricerche varie effettuate mediante motore di ricerca www.google.it

36
Indice delle figure

Figura 1 – architettura .NET Framework...................................................................................................9


Figura 2 – Use Case diagram...................................................................................................................11
Figura 3 – Activity diagram.....................................................................................................................12
Figura 4 - Class Diagram.........................................................................................................................14
Figura 5 – scelta versione framework......................................................................................................16
Figura 6 - interfaccia grafica....................................................................................................................21
Figura 7 - scansione e visualizzazione.....................................................................................................22
Figura 8 - scelta modello di scansione.....................................................................................................22
Figura 9 - finestra gestione modelli di scansione.....................................................................................22
Figura 10 - selezione CV.........................................................................................................................23
Figura 11 - scelta messaggio con allegato................................................................................................23
Figura 12 - scelta cartella per salvataggio allegato..................................................................................23
Figura 13 - conferma salvataggio allegato...............................................................................................24
Figura 14 - preview del CV da acquisire.................................................................................................24
Figura 15 - pulsante avvio scansione e scelta modello di scansione........................................................25
Figura 16 - pulsante per la visualizzazione CV dopo l'acquisizione........................................................25
Figura 17 - com'è strutturato il CV al termine dell'acquisizione..............................................................25
Figura 18 - gestione dei modelli di scansione..........................................................................................25
Figura 19 - finestra per la gestione dei modelli di scansione...................................................................26
Figura 20 - sezione dedicata alle impostazioni generali del programma.................................................26
Figura 21 - classe per la gestione impostazioni programma....................................................................28
Figura 22 - classi utilizzate per la scansione............................................................................................28
Figura 23 - classe per la trasformazione in formato XPS........................................................................29
Figura 24 - la classe CVPageLexer.cs......................................................................................................31
Figura 25 - file XML risultato della scansione........................................................................................33

37

Potrebbero piacerti anche