Précédent   Forum du club des développeurs et IT Pro > Autres langages > XML/XSL et SOAP > APIs
APIs DOM, SAX, JAXP,STAX... leur fonctionnement, leurs implémentations Avant de poster -> FAQ XML
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 13/05/2010, 10h17   #1
lvfco
Invité régulier
 
Inscription : avril 2010
Messages : 45
Détails du profil
Informations forums :
Inscription : avril 2010
Messages : 45
Points : 6
Points : 6
Par défaut Parser HTML avec Cobra et récupérer du blanc via XPath

Bonjour à tous,

J'ai posé la question également dans la rubrique Swing/Awt, mais à la réflexion, je pense que c'est plus adapté de poser ici mon problème....

Alors, voilà je fais du parsing de HTML avec Cobra en utilisant des recherches directement avec XPath.

Je m'appuie pour ce faire sur l'exemple donné dans leur site et repris ci-dessous:

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import javax.xml.xpath.*;
import javax.xml.parsers.*;
import java.util.logging.*;
 
import org.lobobrowser.html.UserAgentContext;
import org.lobobrowser.html.parser.*;
import org.lobobrowser.html.test.SimpleUserAgentContext;
import org.w3c.dom.NodeList;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
 
public class ParseAnchorsTest {
    private static final String TEST_URI = "http://lobobrowser.org";
 
    public static void main(String[] args) throws Exception {
        // Disable most Cobra logging.
        Logger.getLogger("org.lobobrowser").setLevel(Level.WARNING);
        UserAgentContext uacontext = new SimpleUserAgentContext();
        // In this case we will use a standard XML document
        // as opposed to Cobra's HTML DOM implementation.
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        URL url = new URL(TEST_URI);
        InputStream in = url.openConnection().getInputStream();
        try {
            Reader reader = new InputStreamReader(in, "ISO-8859-1");
            Document document = builder.newDocument();
            // Here is where we use Cobra's HTML parser.            
            HtmlParser parser = new HtmlParser(uacontext, document);
            parser.parse(reader);
            // Now we use XPath to locate "a" elements that are
            // descendents of any "html" element.
            XPath xpath = XPathFactory.newInstance().newXPath();
            NodeList nodeList = (NodeList) xpath.evaluate("//table/tr/td/child::text()", document, XPathConstants.NODESET);
            ...
        } finally {
            in.close();
        }
    }
}
A la différence près que je cherche les tables et non les liens. J'ai donc créé une instruction XPath pour ça:

Code :
//table/tr/td/child::text()"
Le problème, c'est que si dans une des cellules de ma table j'ai du vide, l'instruction XPath ne me le remontera pas.

Avez-vous une solution...je cale !
lvfco est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/05/2010, 15h09   #2
polymorphisme
Modérateur
 
Avatar de polymorphisme
 
Homme Grégory Roche
Publishing
Inscription : octobre 2009
Messages : 1 424
Détails du profil
Informations personnelles :
Nom : Homme Grégory Roche
Âge : 39
Localisation : France, Gironde (Aquitaine)

Informations professionnelles :
Activité : Publishing

Informations forums :
Inscription : octobre 2009
Messages : 1 424
Points : 2 333
Points : 2 333
Bonjour,

en effet, si une cellule ne contient pas de texte alors l'expression Xpath est évaluée avec la valeur nulle.

Pour tester si le texte est vide, tu peux utiliser l'expression :
Code :
//table/tr/td/child::text()=''
__________________
Article : Installation de Cocoon
Je ne réponds pas aux MP à caractère technique.
polymorphisme est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/05/2010, 00h05   #3
lvfco
Invité régulier
 
Inscription : avril 2010
Messages : 45
Détails du profil
Informations forums :
Inscription : avril 2010
Messages : 45
Points : 6
Points : 6
J'ai testé, mais ça ne marche pas dans mon exemple...

En fait, j'ai changé d'approche. Mon but est de récupérer la table HTML en prenant chaque balise (<table>, <tr>, <td>) afin de constituer un document DOM à l'issue du parsing.
J'utilise le parseur XPath fourni avec le JDK 5.

Je procède ainsi:

Je commence par filtrer les tables qui m'intéresse par l'instruction XPath ("//table[@class='simple']") qui me renvoie 2 noeuds.
Je boucle ensuite sur ce premier résultat, définit comme noeud courant la première table, et cherche ensuite les lignes via l'expression XPath ("./tr"), en passant le noeud courant en paramètre.
Je récupère 7 lignes (valeur de lengthRow), je positionne le noeud courant sur la première ligne et je recommence pour récupérer les cellules via l'expression XPath ("./td") toujours en passant le noeud courant en contexte.

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 
        XPath xpa = XPathFactory.newInstance().newXPath();
        NodeList nodeList = (NodeList) xpa.evaluate("//table[@class='simple']", document, XPathConstants.NODESET);
        int length = nodeList.getLength();
        Element noeudCourant = null;
        for (int i = 0; i < length; i++) {
            noeudCourant = (Element) nodeList.item(i);
            NodeList nodeListRow = (NodeList) xpa.evaluate("./tr", noeudCourant, XPathConstants.NODESET);
            int lengthRow = nodeListRow.getLength();
            for (int j = 0; j < lengthRow; j++) {
                System.out.println("j: " + j);
                noeudCourant = (Element) nodeListRow.item(j);
                NodeList nodeListCell = (NodeList) xpa.evaluate("./td", noeudCourant, XPathConstants.NODESET);
                int lengthCell = nodeListCell.getLength();
...}
}
et ça a l'air de marcher !
lvfco est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/05/2010, 10h27   #4
polymorphisme
Modérateur
 
Avatar de polymorphisme
 
Homme Grégory Roche
Publishing
Inscription : octobre 2009
Messages : 1 424
Détails du profil
Informations personnelles :
Nom : Homme Grégory Roche
Âge : 39
Localisation : France, Gironde (Aquitaine)

Informations professionnelles :
Activité : Publishing

Informations forums :
Inscription : octobre 2009
Messages : 1 424
Points : 2 333
Points : 2 333
Bonjour,

fait attention du fait que tu utilise du HTML ... qui n'est pas du XML.
__________________
Article : Installation de Cocoon
Je ne réponds pas aux MP à caractère technique.
polymorphisme est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/05/2010, 15h41   #5
lvfco
Invité régulier
 
Inscription : avril 2010
Messages : 45
Détails du profil
Informations forums :
Inscription : avril 2010
Messages : 45
Points : 6
Points : 6
Oui, je me suis déjà rendu compte qu'il fallait faire attention au fait qu'on avait du HTML et non du XML. J'ai constaté ça quand j('ai essayé d'utiliser l'API JDOM...

Là, dans le cas présent, si je parse mon flux HTML en entrée, je ne vois pas ce qui peut m'empêcher de créer ensuite un document DOM avec pour balises, les balises HTML pour les tables et ensuite sérialiser btout ça dans un fichier ...
lvfco est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Cette discussion est résolue.
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 13h51.


 
 
 
 
Partenaires

Hébergement Web