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>&lt;allPlayers&gt;</xsl:text>
<br/>
<xsl:for-each select=".//tidy//h1[@id='firstHeading']">
<xsl:text>&lt;players club=&quot;</xsl:text><xsl:value-of select="."/><xsl:text>
&quot; &gt;</xsl:text>
<br/>
<xsl:for-each select="..//table[@class='ineed']/tr[@class='vcard agent']">
<tr><xsl:text>&lt;player&gt;</xsl:text></tr>
<br/>
12
UdeM
TP1-IFT6281
Wei SHEN
<tr>
<xsl:text>&lt;number&gt;</xsl:text>
<xsl:value-of select="./td[@style='text-align: right;']"/>
<xsl:text>&lt;/number&gt;</xsl:text>
<br/>
</tr>
<tr>
<xsl:text>&lt;position&gt;</xsl:text>
<xsl:value-of select="./td[@style='text-align: center;']/a"/>
<xsl:text>&lt;/position&gt;</xsl:text>
<br/>
</tr>
<tr>
<xsl:text>&lt;name&gt;</xsl:text>
<xsl:value-of select="./td/span[@class='fn']/a"/>
<xsl:text>&lt;/name&gt;</xsl:text>
<br/>
</tr>
<tr><xsl:text>&lt;/player&gt;</xsl:text></tr>
<br/>
</xsl:for-each>
<xsl:text>&lt;/players&gt;</xsl:text>
<br/>
</xsl:for-each>
<xsl:text>&lt;/allPlayers&gt;</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