TP XML - Département d`histoire
Transcription
TP XML - Département d`histoire
Université de Montréal TP XML IFT6281-Web Sémantique Wei SHEN 12/02/2012 UdeM TP1-IFT6281 Wei SHEN 1 Introduction Merci de visiter mon TP avec l’URL ci-dessous : https://www.webdepot.umontreal.ca/Usagers/p0996829/MonDepotPub lic/TP_XML/index.html?uniq=-gvfu9t 1.1 Sujet : Premier League Pour ce TP, je choisi un sujet sportif : Premier League anglaise. Le Championnat d'Angleterre de football est appelé Premier League, qui se situe presentement au premier place dans le monde. Ce championnat regroupe vingt équipes quis disputent chacune 38 matchs. Comme football est un grand loisir pour moi, ca me plait beaucoup de travail sur ce sujet. Pour un championnat, il y a toujours 3 aspects principaux : clubs, joueurs et matchs. Et bien sur, c’est bien ca que je veux vous présenter. A la fin, j’ai pris les données bien raffiné comme l’arbre suivant : Je divise les informations dans 3 grandes parties : Clubs : les informations de base d’un club et tous ses joureurs. Seasons : j’essaie de regrouper les matche par année. Honor : je vous raconte aussi un peu d’histoire à propos ce meilleur championnat du monde. 1.2 Procédure de l’extraction des données L’objectif de ce projet est d’extraire des données utiles sur l’internet et les transmis sous forme XML afin de les afficher dans un page HTML. Toutes mes données origines du page web en HTML. Pendant cette TP, je n’ai décrit aucun fichier XML manuellement, ni saisi les données à la main. Toutes les opérations sont automatiques. Avant de bien être formalisé, les données sont traitées par 4 étapes : 2 UdeM TP1-IFT6281 Wei SHEN MOZENDA Code HTML original JTidy Brouillon XHTML/XML bien formé XSLT RNC Donnée pur sous forme XML Page HTML contiens ces tableaux HTML Tableaux rendu par XSLT XSLT JavaScript CSS HTML XHTML/XML XML Figure 1 procédure de l’extraction des données Du coup, j’ai utilisé 3 différents méthodes à collecter et extraire les données : Web scraper : Mozenda Je développe un petit programme Java pour collecter les codes HTML du page web et les transforme en XML biens formé en utilisant API JTidy. Extraire les données que je veux par un feuille de style XSLT. Après obtenu le fichier XML, j’ai fait encore 3 chose : Décris un fichier de validation RNC. Les mise en tableaux HTML par stylesheet XSLT A la fin, intégrais les tableaux dans un page HTML bien désigné. 1.3 Les outils utilisé Éditeur XML : oXygen Web scraper : Mozenda et Metaseeker Platform de programmer : Java Eclipse (avec library JTidy) Designer HTML : DreamWreaver 3 UdeM TP1-IFT6281 Wei SHEN A partie de chapitre 2, je vais vous présenter ce TP étape par étape. 2 Resource de l’information Au début, selon l’idée de 3 aspects : clubs, joueurs et matchs, je divise les informations dans 3 grandes parties : Clubs : les informations de base d’un club et tous ses joureurs. Seasons : j’essaie de regrouper les matche par année. Honor : je vous raconte aussi un peu d’histoire à propos ce meilleur championnat du monde. En suite je détaillais un peu ces trois aspects est désigné un plan préliminaire. Ce plan donc deviens un guide très important en tant que je cherche les informations originaux sue le net. Premier League Clubs Seasons Honor Name Rank Champions Ville Match 2ème place Player 3ème place Goals Figure 2 arbre simple XML Voici je vous lister le toutes les données original que je utilisé pour ce tp : Nom et location de 20 clubs du Premier League : http://fr.wikipedia.org/wiki/Championnat_d%27Angleterre_de_football 4 UdeM TP1-IFT6281 Wei SHEN Les joueurs de chaque club : http://fr.wikipedia.org/wiki/Arsenal_Football_Club (20 pages : une par club) Rank de chaque année http://www.premierleague.com/en-gb/matchday/league-table.html/ (une page par season) Le score de chaque match http://www.premierleague.com/engb/clubs/profile.statistics.html/arsenal?playedAt=HOME&timelineView=BY_SEASON&toSeason =2011-2012#clubsTabsGoals (centaine page comme ca, car les données sont décentralisé) Liste du champion de chaque année http://en.wikipedia.org/wiki/List_of_English_football_champions 3 Collecter des informations Jusqu'à maintenant, toute les données que j’ai besoin sont consisté dans ces centaine page HTML originaux. Comment je les prends sur l’Internet sans faisant copie-coller. Ici, j’ai utilisé deux méthodes : Je développé une petit programme «conversion.java» en utilisant un API JTidy. Outil Web scraper MOZENDA 3.1 API JTidy Pour l’ensemble des pages sous même forme comme Wikepedia, je suis capable d’extraire directement les données de la page original par XSLT. Je choisi donc de les transforme vers XHTML bien formé, ce qui me permet de les traiter par Stylesheet XSLT ultérieurement. Ce programme consiste de 3 fonctions principales : «enregisreHTML» : Enregistrer automatiquement le code source HTML par une adresse URL comme parametre. Je copie tous les URL que je veux dans un fichier TXT, cette fonction va lire ce liste de URL et crée le ficher htm pour le code source. public static void enregistrerHTML(String AddURL,String original,int x){ try{ HttpURLConnection Conn; 5 UdeM TP1-IFT6281 Wei SHEN URL myurl=new URL(AddURL); Conn=(HttpURLConnection)myurl.openConnection(); BufferedReader in=new BufferedReader(new InputStreamReader(Conn.getInputStream())); String line; File newFile=new File(original+x+".htm"); PrintWriter pw=new PrintWriter(new FileOutputStream(newFile)); while((line=in.readLine())!=null){ System.out.println(line); pw.println(line); } }catch(FileNotFoundException e) { }catch(IOException e) { } } Figure 3 code de la fonction «enregistrerHTML» «getFileName» collecter le chemin physique de chaque fichier htm, et les retourne. public static String[] getFileName (String path){ int i; String[] fileName=new String[1000]; File dir=new File(path); File[] fileList=dir.listFiles(); for(i=0;i<fileList.length;i++){ fileName[i]=fileList[i].getAbsolutePath(); } return fileName; } Figure 4 code de la fonction «getFileName» «html2xml» est la fonction principale, il est assez simple, appel seulement une méthode tidy.parse(). Il est un vérificateur syntaxique qui corrige les fautes dans fichier HTML et la bien mise en forme sous XHTML. Ce qui est important ici est les configurations de JTidy. Il nous donne beaucoup de choix mais en même temps il nous confuse beaucoup. Il me prend beaucoup de temps pour choisir un propre ensemble de configuration pour moi. public static void html2xml(String fileName, String destination,int t){ Tidy tidy=new Tidy(); tidy.setDropEmptyParas(true); tidy.getDropFontTags(); 6 UdeM TP1-IFT6281 Wei SHEN tidy.setForceOutput(true); tidy.setXHTML(true); tidy.setPrintBodyOnly(true); tidy.setTrimEmptyElements(true); tidy.setXmlPi(true); tidy.setHideComments(true); tidy.setLogicalEmphasis(true); tidy.setConfigurationFromFile("C:/Users/Toshiba/workspace/test_jtidy/src /jtidy_config.txt"); tidy.setTidyMark(true); try{ BufferedInputStream in=new BufferedInputStream(new FileInputStream(new File(fileName))); BufferedOutputStream out=new BufferedOutputStream(new FileOutputStream(new File(destination + t + ".xml"))); tidy.parse(in, out); in.close(); out.close(); }catch(FileNotFoundException e) { }catch(IOException e) { } } Figure 5 code de la fonction de «html2xml» Maintenant je vous montre un peu les fichier que j’ai obtenu. Voici une liste de url que je chosais. Figure 6 fichier de URL En suite voici les code source html et les fichier XHTML bien formet, il sont tous copie dans son propre répertoire : 7 UdeM TP1-IFT6281 Wei SHEN Figure 7 fichier htm et xhtml crée Les données dans les ficher par exemple 0.xml, n’est que les code XHTML du page bien formée, les données pure que je veux se cache encore dans la page, faut que je les extraire ensuite par le XSLT. <?xml version="1.0" encoding="UTF-8"?> <tidy> <div id="mw-page-base" class="noprint"></div> <div id="mw-head-base" class="noprint"></div> <div id="content"> <a id="top"></a> <div id="mw-js-message" style="display:none;"></div> <div id="siteNotice"> </div> <h1 id="firstHeading" class="firstHeading">Arsenal F.C.</h1> <div id="bodyContent"> <div id="siteSub">From Wikipedia, the free encyclopedia</div> <div id="contentSub"></div> <div id="jump-to-nav">Jump to: <a href="#mw-head">navigation</a>, <a href="#p-search">search</a></div> <div lang="en" dir="ltr" class="mw-content-ltr"> <div class="dablink">For other uses, see <a href="/wiki/Arsenal_(disambiguation)" title="Arsenal (disambiguation)">Arsenal (disambiguation)</a>.</div> <div class="metadata topicon" id="protected-icon" style="display:none; right:55px;"> <a href="/wiki/Wikipedia:Protection_policy#semi" title="This article is semi-protected."> <img alt="Page semi-protected" Figure 8 une partie du code XHTML originale obtenu 8 UdeM TP1-IFT6281 Wei SHEN 3.2 Web Scraper MOZENDA Au début je tendais de collecter toutes mes données par le API JTidy. Jusqu'à certain moment quand je commence à collecter les scores de chaque match, je trouve que les données sur le site officiel du premier league (http://www.premierleague.com/engb/clubs/profile.statistics.html/arsenal?playedAt=HOME&timelineView=BY_SEASON&toSeason =2011-2012#clubsTabsGoals ) sont fourni par Javascript. Donc, JTidy n’est pas capable d’obtenir les codes statiques de HTML après traiter d’abord le Javascript. Donc, je commence à chercher les outils Web scraper. J’ai quand même trouvé au minimum 3 scrapers sur l’internet : Metaseeker Web Content Extractor MOZENDA Après une comparaison, je choisi a la fin MOZENDA en tenant compte ses performances. Il est capable de mettre les données choisis en tableaux et les sorte en fichier XML. Vous pouvez voire, pour certains tableaux sur l’internet, il collecter purement les données bien raffiné. Je peux même les utilisé directement sans aucun traitement. Je vous montre un exemple : un tableau sur le site Wikipedia, Mozenda me rende 100% des données parfaitement organisé : Figure 9 page origine de données «First Division» Les XML sortie: <Allitems> <Item> <season>1892–93</season> <champions>Sunderland</champions> 9 UdeM TP1-IFT6281 Wei SHEN <runnersUp>Preston North End</runnersUp> <thirdPlace>Everton</thirdPlace> <leadingGoalscorer>John Campbell</leadingGoalscorer> <goals>31</goals> </Item> <Item> <season>1893–94</season> <champions>Aston Villa</champions> <runnersUp>Sunderland</runnersUp> <thirdPlace>Derby County</thirdPlace> <leadingGoalscorer>Jack Southworth</leadingGoalscorer> <goals>27</goals> </Item> Figure 10 les données «First Division» biens organisé scrapé par Mozenda Mais pour les donnés comme le « score du match » est seulement bien retiré, mais encore loin d’être bien organisé, les score du «home team» et «away team» se situe dans deux différent fichiers. Faut que je les traiter par XSLT aussi : <Allitems> <Item> <opponent>v Aston Villa</opponent> <score>1</score> </Item> <Item> <opponent>v Blackburn</opponent> <score>0</score> </Item> <Item> <opponent>v Blackpool</opponent> <score>6</score> </Item> <Item> <opponent>v Bolton</opponent> <score>4</score> </Item> <Allitems> <Item> <opponent>v Aston Villa</opponent> <scored>2</scored> </Item> <Item> <opponent>v Blackburn</opponent> <scored>0</scored> </Item> 10 UdeM TP1-IFT6281 Wei SHEN <Item> <opponent>v Bolton</opponent> <scored>1</scored> </Item> <Item> <opponent>v Chelsea</opponent> <scored>1</scored> </Item> Figure 11 les données «matchs» mal organisé scrapé par Mozenda 4 Filtrage des informations par XSLT Jusqu'à moment, j’ai 3 types de donnée obtenu : page XHTML original Les données pure en XML mais mal organisé Les données XML bien organisé Les deux premiers ont besoin d’un filtrage par XSLT. Je vous montre d’abord les données des joueurs dans le code XHTML original, les text en jeune sont ce que je veux : <table class="ineed" border="0" cellspacing="0" cellpadding="2"> <tr bgcolor="#AAD0FF"> <th width="1%">No.</th> <th width="1%"></th> <th width="1%">Position</th> <th width="75%">Player</th> </tr> <tr class="vcard agent"> <td style="text-align: right;">1</td> <td style="text-align: right;"> <span class="flagicon"> <a href="/wiki/Spain" title="Spain"> <img alt="Spain" src="//upload.wikimedia.org/wikipedia/en/thumb/9/9a/Flag_of_Spain.svg/22pxFlag_of_Spain.svg.png" width="22" height="15" class="thumbborder" /> </a> </span> </td> <td style="text-align: center;"> <a href="/wiki/Goalkeeper_(association_football)" title="Goalkeeper (association football)">GK</a> 11 UdeM TP1-IFT6281 Wei SHEN </td> <td> <span class="fn"> <a href="/wiki/Manuel_Almunia" title="Manuel Almunia">Manuel Almunia</a> </span> </td> </tr> Figure 12 les données «joueur» originales Mon objectif n’est pas seulement de raffiner seulement les données, la valeur, mais aussi les balises XML. C'est-à-dire une ficher XML complète comme suivant : <players club="Arsenal F.C. " > <player> <number>1</number> <position>GK</position> <name>Manuel Almunia</name> </player> <player> <number>2</number> <position>MF</position> <name>Abou Diaby</name> </player> Figure 13 les données biens organisé après le traitement Donc, ma solution est d’afficher les données, les valeurs avec les balises en utilisant Stylesheet XSLT. C'est-à-dire je fais les pages HTML sorties affichés comme le code XML. Voici un code XSLT qui vous montre comment je fais : <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:template match="/"> <xsl:text><allPlayers></xsl:text> <br/> <xsl:for-each select=".//tidy//h1[@id='firstHeading']"> <xsl:text><players club="</xsl:text><xsl:value-of select="."/><xsl:text> " ></xsl:text> <br/> <xsl:for-each select="..//table[@class='ineed']/tr[@class='vcard agent']"> <tr><xsl:text><player></xsl:text></tr> <br/> 12 UdeM TP1-IFT6281 Wei SHEN <tr> <xsl:text><number></xsl:text> <xsl:value-of select="./td[@style='text-align: right;']"/> <xsl:text></number></xsl:text> <br/> </tr> <tr> <xsl:text><position></xsl:text> <xsl:value-of select="./td[@style='text-align: center;']/a"/> <xsl:text></position></xsl:text> <br/> </tr> <tr> <xsl:text><name></xsl:text> <xsl:value-of select="./td/span[@class='fn']/a"/> <xsl:text></name></xsl:text> <br/> </tr> <tr><xsl:text></player></xsl:text></tr> <br/> </xsl:for-each> <xsl:text></players></xsl:text> <br/> </xsl:for-each> <xsl:text></allPlayers></xsl:text> </xsl:template> </xsl:stylesheet> Figure 14 code XSLT pour filtrer les données «joueur» Les deux ligne de text ajouté autour de la valeur sont affiché comme la balise. Finalement, le page html rendu affiche dans le navigateur est exactement ce que j’attends. [ !!!] Une chose important que je mentionne ici est que : en faite je triche un peu dans cette étape. Parce que je n’arrive pas à fixer le tableau contenant les données. Du coup, je ajoute une petit attribut «class=`ineed`» pour chaque tableau que j’ai besoin. Ca c’est de seule opération ``manuel`` que j’ai fait dans ce TP. Ensuite je filtrer toutes mes données pas encore bien organisé de la même facon. 13 UdeM TP1-IFT6281 Wei SHEN 5 Fichier XML final et Fichier de validation RNC 5.1 Collecter des petites morceaux dans un fichier XML final Après avoir toutes transformé vers données XML. J’ai écrit des petites fonctions pour collecter des petits morceaux dans une seule fichier XML final. Je vous liste seulement une comme exemple : import import import import import import import java.io.BufferedReader; java.io.File; java.io.FileNotFoundException; java.io.FileOutputStream; java.io.FileReader; java.io.IOException; java.io.PrintWriter; import org.xml.sax.SAXException; public class collection_match { public static void main(String[] args) throws SAXException { int i; String path="C:/Users/Toshiba/Desktop/xml/match"; File total=new File("C:/Users/Toshiba/Desktop/xml/match/total.xml"); File dir=new File(path); File[] fileList=dir.listFiles(); try{ PrintWriter pw=new PrintWriter(new FileOutputStream(total)); for(i=0;i<fileList.length;i++){ BufferedReader br=new BufferedReader(new FileReader(fileList[i])); String line; String name=fileList[i].getName(); pw.println("<"+name+">"); pw.println(""); while((line=br.readLine())!=null){ pw.println(line); } pw.println(""); pw.println(""); pw.println("</"+name+">"); pw.println(""); pw.println(""); } }catch(FileNotFoundException e) { }catch(IOException e) { } } } Figure 15 petit programme pour collecter les données dans divers fichers 14 UdeM TP1-IFT6281 Wei SHEN 5.2 Fichier de validation RNC C’est vraiment l’étape la plus facile dans ce projet, je décris juste une ficher de RNC de validation pour assurer que les fichiers XML est bien formé. Voici le code : default namespace = "http://en.wikipedia.org/wiki/Premier_League" datatypes xsd = "http://www.w3.org/2001/XMLSchema-datatypes" start=premierLeague premierLeague = element premierLeague { element clubs{element club{Club}*}, element seasons{element season{Season}*}, element honor{Honor} } Club = element name{text}, element ville{text}, element players{ attribute club{text}, element player{Player}*}? Player = element number{xsd:nonNegativeInteger}, element position{text}, element name{text} Season = attribute year{text}, element ranks{element Items{items}*}, element matchs{attribute season{text}, element match{Match}*} items = element rank{text}?, element clubName{text}?, element play{text}?, element win{text}?, element drawn{text}?, element lost{text}?, element goal_for{text}?, element goal_against{text}?, element net{text}?, element points{text}? Match = element home{text}, element away{text}, element score{text} Honor = element FirstDivision{element Item{item}*}, element PremierLeague{element Item{item}*} item = element season{text}, element champions{text}, 15 UdeM TP1-IFT6281 Wei SHEN element runnersUp{text}, element thirdPlace{text}, element leadingGoalscorer{text}, element goals{text} Figure 16 fichier de validation RNC 6 Mise en forme en tableaux HTML par Stylesheet XSLT Après avoir le bon fichier XML, je commence à penser l’affichage. Mon idée est de les montrer tous en tableaux. Un autre raison est qu’oXygen n’est pas un très bon éditeur de page HTML. Je le utiliser juste pour construire les tableaux des données. Et ensuite je vais essayer de les intégrer dans une page HTML biens désigné en Javascript et CSS. L’outil est toujours la même chose : Stylesheet XSLT. La seule différente cette fois est que je veux les afficher en tableaux. Voici un petit exemple et son résultat : <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:template match="/"> <html> <head> </head> <body> <div> <xsl:apply-templates select="./premierLeague/seasons/season"/> </div> </body> </html> </xsl:template> <xsl:template match="season"> <h1><center><xsl:value-of select="./@year"/></center></h1> <h1><b>Rank</b></h1> <center> <table> <tr align="left" class="title"> <td><b>Rank</b></td> 16 UdeM TP1-IFT6281 Wei SHEN <td><b>Club</b></td> <td><b>Game Play</b></td> <td><b>Win</b></td> <td><b>Drawn</b></td> <td><b>Lost</b></td> <td><b>Goal For</b></td> <td><b>Goal Against</b></td> <td><b>Goal Net</b></td> <td><b>Points</b></td> </tr> <xsl:apply-templates select="./ranks/Items"></xsl:apply-templates> </table> </center> <h1><b>Match Score</b></h1> <center> <table> <tr align="left" class="title2"> <td><b>Team Home</b></td> <td><b>Team Away</b></td> <td><b>Game Score</b></td> </tr> <xsl:apply-templates select="./matchs/match"></xsl:apply-templates> </table> </center> </xsl:template> <xsl:template match="Items"> <tr align="left"> <td><xsl:value-of select="rank"/></td> <td><xsl:value-of select="club"/></td> <td><xsl:value-of select="play"/></td> <td><xsl:value-of select="win"/></td> <td><xsl:value-of select="drawn"/></td> <td><xsl:value-of select="lost"/></td> <td><xsl:value-of select="goal_for"/></td> <td><xsl:value-of select="goal_against"/></td> <td><xsl:value-of select="net"/></td> <td><xsl:value-of select="points"/></td> </tr> </xsl:template> <xsl:template match="match"> <tr align="left"> <td><xsl:value-of select="home"/></td> 17 UdeM TP1-IFT6281 Wei SHEN <td><xsl:value-of select="away"/></td> <td><xsl:value-of select="score"/></td> </tr> </xsl:template> </xsl:stylesheet> Figure 17 code XSLT pour afficher les données «rank» dans un tableau Et voici le résultat: Figure 18 le tableau affiché dans un navigateur 18 UdeM TP1-IFT6281 Wei SHEN 7 Intégrer dans un site web HTML Maintenant j’ai presque tout fini. La dernière étape est de bien désigner un site web très joli, et puis ajouter ces tableaux dans la page. S’est un travail vraiment intéressant, n’est-ce pas? Voici mon propre site. Tu pense qu’il est belle ou pas? 19 UdeM TP1-IFT6281 Wei SHEN Figure 19 mon site «Premier League» Voila jusqu'à maintenant le tp1 est fini. Vous pouvez chercher toutes les informations à propose du Premier League sur les tableaux. Voici l’URL de mon site : https://www.webdepot.umontreal.ca/Usagers/p0996829/MonDepotPub lic/TP_XML/index.html?uniq=-gvfu9t Merci de le visiter! J’espère qu’il te plait. 20 UdeM TP1-IFT6281 Wei SHEN [!!!] Petit notation : les mauvais codages dans la page est à cause de l’incompatibilité entre le codage local et la page original. Ce n’est pas possible pour moi de les tous corrigé à la main en tenant compte le taille de données. 21