Probléme avec une expression régulière.

Eléphanteau du PHP | 13 Messages

23 mai 2007, 00:28

Bonsoir,
J'ai encore quelques questions :wink: :

Le motif
//qq chose/../*
est bien synonyme de
//qq chose/parent::*
?

Cette ligne compte bien le nombre de ligne (parent de td) ?

Code : Tout sélectionner

$qnumber = 'count(//td[contains(text(),"'.$needle.'")]/../*)';
Comment traiter le cas ou un tableau est inclus dans une ligne ?
Aprés avoir trouvé la chaine "Chiffre d'affaires", je suis confronté à un tableau inséré dans des colonnes fusionnées !
<TABLE BORDER="0" CELLPADDING="1" CELLSPACING="1" WIDTH="100%" CLASS="bright">

  <TR BGCOLOR="#FFFFFF">
    <TD COLSPAN="6">
      <TABLE BORDER="0" CELLPADDING="1" CELLSPACING="0" WIDTH="100%">
	<TR><TD CLASS="ligneItem" COLSPAN="2"><IMG SRC="http://img.boursorama.com/i/d.gif" WIDTH="1" HEIGHT="1"></TD></TR>
	<TR><TD VALIGN="TOP" CLASS="TitreE"><B>Compte de résultat</B></TD></TR>
      </TABLE>
    </TD>
  </TR>

	<tr><td class="l20" colspan="6" height="10"></td></tr>
  <TR CLASS="entetetab">
    <TD ALIGN="CENTER"><B>milliers EUR</TD>
				<TD ALIGN="CENTER"><B>12.01</TD>
				<TD ALIGN="CENTER"><B>12.02</TD>
				<TD ALIGN="CENTER"><B>12.03</TD>
				<TD ALIGN="CENTER"><B>12.04</TD>

				<TD ALIGN="CENTER"><B>12.05</TD>
		  </TR>

	
  <TR CLASS="L20">
    <TD NOWRAP ALIGN="LEFT">&nbsp;&nbsp;&nbsp;Chiffre d'affaires</TD>
Si vis pacem para bellum

Mammouth du PHP | 505 Messages

23 mai 2007, 02:27

Le motif
//qq chose/../*
est bien synonyme de
//qq chose/parent::*
?
Oui, mais je trouve .. plus lisible que parent::
Cette ligne compte bien le nombre de ligne (parent de td) ?

Code : Tout sélectionner

$qnumber = 'count(//td[contains(text(),"'.$needle.'")]/../*)';
Non, elle compte le nombre de colonne. On recherche tous les td qui contienne un certain texte, le noeuds courant est donc l'intérieur du td, on remonte d'un cran et on selectionne tous les fils soit tous les td de la ligne qui contenait $needle.


Comment traiter le cas ou un tableau est inclus dans une ligne ?
Aprés avoir trouvé la chaine "Chiffre d'affaires", je suis confronté à un tableau inséré dans des colonnes fusionnées !
En faisant un peu différment je pense, j'avais proposé ca pour donnée une idée. Plutot que de compter les noeuds, il faut peut etre etre plus carré, chercher tous les tr du tableau qui t'interresse, puis parcourrir tous les td de chaque tr. Dans chaque td, vérifier si y a un tableau et faire la meme manip (récursion)


Attention, ce bout code est a titre d'exemple, il ne gère pas le cas ou il y a plusieurs tableau dans un td par exemple, je t'indique la route, a toi ensuite de faire le chemin...

<?php

$doc = new DOMDocument();
@$doc->loadHTMLFile("http://www.boursorama.com/profil/resume_societe.phtml?symbole=1rPARR");
$xpath = new DOMXPath($doc);

// On encode la chaine a chercher en utf8
$needle = utf8_encode("Chiffre d'affaires");
// On recherche  dans tous les td une case de tableau qui contient la chaine rechercher, puis on recupere tous les tr du tableau qui match
$query= '//td[contains(text(),"'.$needle.'")]/../../*';
$trList = $xpath->query($query,$doc->documentElement);

function getData($nodes) {
	$line=0;
	foreach ($nodes as $tr) {
		$row=0;
		$tds = $tr->getElementsByTagName('td');
		foreach($tds as $td) {
			// Check si y a des tables en noeuds enfants
			$fiston = $td->getElementsByTagName('table') ;
			// Si oui, on recurse
			if($fiston->length) {
                                // J'ajoute un index bidon 'récursion' pour pouvoir le repérer plus facilement dans le dump
				// @todel une fois compris
				$data[$line][$row++]['recursion'] =  getData($fiston);
			}
			// Si non, on recupe jsute la valeur du noeud
			else {
				$data[$line][$row++] = $td->nodeValue;
			}
		}
		$line++;
		
	}
	return $data;
}

$data = getData($trList);
var_export($data);

Eléphanteau du PHP | 13 Messages

03 juin 2007, 07:57

Bonjour,
De retour après quelques jours de congés ...

Dans la boucle :
foreach($tds as $td) {
on cherche les balises "table" :
      // Check si y a des tables en noeuds enfants
            $fiston = $td->getElementsByTagName('table') ;
Je voudrais chercher parmi les fiston les td qui ont un attribut class.
La fonction getElementsByClassName n'existe pas !
J'ai pensé à
$chercheEntete= '//@class';
mais je n'arrive pas à l'implémenter.
Comment faire ?
Si vis pacem para bellum

Mammouth du PHP | 505 Messages

03 juin 2007, 12:07

e voudrais chercher parmi les fiston les td qui ont un attribut class.
La fonction getElementsByClassName n'existe pas !
// ==> tous les

td ==> ce que tu cherches

[] => ajoute une condition

@class => l'attribut class

soit

//td[@class]



Toi tu demandes //@class => tous les attributs class

Eléphanteau du PHP | 13 Messages

03 juin 2007, 12:51

Quelle syntaxe utiliser pour effectuer cette requête
//td[@class]
sur le sous-ensemble (objet) $nodes, obtenu par
$trList = $xpath->query($query,$doc->documentElement);
?
Si vis pacem para bellum

Mammouth du PHP | 505 Messages

03 juin 2007, 20:51

dans ton expression, $query contient déjà en toute logique une expression xpath, donc il te suffit de concaténer. Je ne sais pas ce que contient query, je ne peux pas donc etre plus précis mais si tu fais qq chose du genre :
$query .= '//td[@class]';
$trList = $xpath->query($query,$doc->documentElement);
ca devrait le faire