• Non ci sono risultati.

4.3 Scelte implementative

4.3.2 XMLParserLib

Questa libreria verrà utilizzata per il parsing e per la validazione di un documento XML rappresentante una mappa causale di Bayes.

Un parser XML è un modulo software che si colloca tra l'applicazione e il documento XML, e permette all'applicazione di accedere al contenuto e alla struttura del documento. Esistono due tipi di parser: validanti e non validanti. I primi, oltre a controllare se un documento è ben-formato, cioè che ogni elemento sia racchiuso tra due tag (uno di apertura e uno di chiusura), controlla pure se esso è un documento

XML valido, cioè se è fedele alle regole definite nel suo XML Schema. I parser non validanti, invece, si preoccupano solo di vedere se un documento è ben formato. Per la realizzazione della nostra libreria abbiamo usato Xerces [XERCES], un parser validante free tra i più robusti e affidabili.

Ci sono due modi per interfacciare un parser con una applicazione: usando un'interfaccia object-based (DOM) oppure usando un interfaccia event-based (SAX). Con l'approccio object-based, il parser costruisce esplicitamente in memoria un albero che contiene tutti gli elementi del documento XML. Con l'approccio event- based, invece, il parser genera un evento ogni qual volta incontra, durante la lettura del documento XML, un elemento, un attributo, o del testo; ci sono eventi per i tag di apertura e di chiusura, per gli attributi, per il testo, per le entità e così via.

Xerces implementa entrambi i tipi di parser mediante le classi DOMBuilder e

SAXParser.

Nel nostro caso la scelta fra DOM e SAX non è risultata rilevante, e abbiamo optato per usare l’approccio object-based (DOM).

Per effettuare il parsing e la validazione del file rappresentante la mappa è sufficiente istanziare un oggetto di tipo MyParserXML passando al costruttore il nome del file da parsare ed in seguito invocare il metodo pubblico Initialize_And_Parsing() che restituisce un puntatatore alla tabella Hash rappresentante la BCM.

La figura 4.14 mostra l’implementazione del namespace XMLParser.

namespace XMLParser { class MyParserXML {

private :

const char * filename; string namenode1; string namenode2; Hash *myTH; Rule *rule; Node *node; bool first_time; bool vincolo; int count; void ExtractItemFromDomTree(DOMNode *n); public :

MyParserXML(const char * filename); Hash * Initialize_And_Parsing(); };

}

La figura 4.15 mostra l’utilizzo della libreria XMLParserLib.

Figura 4.15 - Uso di XMLParserLib

Di seguito vedremo lo pseudo-codice del metodo privato ExtractItemFromDomTree27 che come si nota dalla figura 4.15 fa si che le informazioni racchiuse nell’albero costruito dal parser, vengano estratte e inserite nella tabella Hash che rappresenterà la mappa causale di Bayes in memoria.

ExtractItemFromDomTree(DOMNode n) 1. Rule rule; 2. Hash hash; 3. Node node; 4. constrained=false; 5. name_node =n.getName(); 6. if(name_node==“Baysian_causal_map”) 7. hash=Create_Hash_Object(name_node.getAttribute); 8. if(name_node == “Rule”){ 9. rule=Create_Rule_Object(); 10. rule.setType(name_node.getAttribute); 11. } 12. if(name_node == “Node”){ 13. node=Create_Node_Object; 14. if(constrained) 27

Per l’implementazione vedere in Appendice

XML Schema bcm.xsd Bcm.XML MyXMLParser XML Dom Tree ExtractItemFromDomTree BCM Hash XMLParserLib

15. rule.SetConstrained(node); 16. else 17. rule.SetNode(node); 18. } 19. if(name_node == “Vincolo”) 20. constrained = true; 21. if(name_node == “Probability”){ 22. rule.SetProbOfRule(); 23. if(name_node == “EndRule”){ 24. if(rule.isCorrect){ 25. hash.InsertImplying(rule); 26. hash.InsertImplicate(rule); 27. constrained=false; 28. } 29. } 30. for(child=n.getFirstChild;child!=NULL;child.NextChild) 31. ExtractItemFromDomTree(child);

Figura 4.16 - Pseudo codice per l’estrazione dgli elementi dall’albero rappresentante la mappa causale

ExtractItemFromDomTree prende come argomento l’albero costruito dal parser n e partendo dalla radice percorre l’intero albero facendo di volta in volta dei controlli sul tipo di nodo in esame.

I passi [1-3] sono necessari per la dichiarazione degli oggetti che useremo durante il porcesso di estrazione. Al passo [4] si inizializza la variabile boolena contsrained a

false, questa variabile ha lo scopo di segnalare se un Node deve essere inserito come

implicante come implicato (se il suo valore è false), o come vincolo in un regola (se il suo valore è true). Una volta ricavato il nome del nodo in esame [5], se esso è uguale a “Baysian_causal_map” verrà istanziato un oggetto di tipo Hash, il cui costruttore prende come argomento il numero degli attributi della mappa riportato come attributo dell’elemento (tag) <Baysian_causal_map>28.

Se si tratta di un nodo “Rule” [8] verrà instanziato un oggetto di tipo Rule, dopo di che verrà settato il tipo della regola[10] il cui valore è presente come attributo dell’elemento (tag) <Rule>29.

Nel caso il nodo sia un “Node” verrà istanziato un oggetto di tipo Node i cui arogmenti sono ricavati dagli attributi presenti nell’elemento (tag) <Node>30. Se la variabile constrained ha valore true il Node appena istanziato verrà insertito nella regola come vincolo [15] altrimenti come implicante se è la prima volta che per la

28

Per vedere la lista degli attributi di ogni elemento (tag ) consultare lo Schema XML in Appendice.

29

Come sopra.

30

regola in esame viene instanziato un Node oppure come implicato se è la seconda volta che si istanzia un oggetto Node per la stessa regola [17].

Se il nodo in esame è un “Vincolo” la variabile constrained verrà posta a true [20]. Ciò segnala che tutti gli oggetti Node che verranno istanziati in seguito devono esssere inseriti nella regola come vincoli.

Se il nome del nodo è uguale a “Probability” verrà settata la probabilita’ della regola [22].

L’ultimo caso possibile è quello in cui il nome del nodo in esame è uguale ad

“EndRule”. In questo caso la regola istanziata è completa, ed una volta verificata la

sua correttezza sia sintattica che semantica verrà inserita nella tabella Hash rappresentante la mappa [25-26]. Infine il valore della variabile constrained viene rimesso a false [27].

Il procedimento visto finora verrà ripetutto in maniera ricorsiva per ogni figlio dell’elemento ( tag ) attualmente considerato [30-31].