2017-10-11 3 views
0

J'ai un tableau HTML avec le format ci-dessous: Comme vous pouvez le voir, le premier en-tête 1 est associé à une rangée 1. Le deuxième en-tête 2 a deux rangées - Rangée 2, Rangée 3 associée. L'en-tête 3 est associé à la rangée 4, à la rangée 5 et à la rangée 6.PHP: Simple HTML Dom parser - Parse Table HTML avec en-têtes/rangées inégales de corps

<table> 
<thead> 
    <tr> 
     <th>Header 1</th> 
    </tr> 
</thead> 
<tbody> 
     <tr> 
      <td> 
       Row 1 
      </td> 
     </tr> 
</tbody> 
<thead> 
    <tr> 
     <th>Header 2</th> 
    </tr> 
</thead> 
<tbody> 
     <tr> 
      <td> 
       Row 2 
      </td> 
     </tr> 
     <tr> 
      <td> 
       Row 3 
      </td> 
     </tr> 

</tbody> 
<thead> 
    <tr> 
     <th>Header 3</th> 
    </tr> 
</thead> 
<tbody> 
     <tr> 
      <td> 
       Row 4 
      </td> 
     </tr> 
     <tr> 
      <td> 
       Row 5 
      </td> 
     </tr> 
     <tr> 
      <td> 
       Row 6 
      </td> 
     </tr> 
</tbody> 

Je veux utiliser l'analyseur Dom Simple HTML PHP pour obtenir les données suivantes:

Header 1, Row 1 
Header 2, Row 2, Row 3 
Header 3, Row 4, Row 5, Row 6 

Lorsque j'utilise l'analyseur pour obtenir les étiquettes, elles sont toutes stockées dans un tableau. Toutes les autres balises sont stockées dans un autre tableau lorsque je fais la boucle foreach. Comment préserver l'association des en-têtes avec les lignes lorsque je fais une boucle?

+0

Une raison pour laquelle vous n'utilisez pas l'interface DOMDocument intégrée? – trincot

+0

Montrez votre code s'il vous plait. De quels moyens parlez-vous? – Nima

Répondre

1

Sans voir votre code php existant, il est difficile de dire exactement comment changer ce que vous avez. Mais quelque chose comme ceci fonctionnerait pour votre cas d'utilisation:

//Assuming $html has been set to your html block 
$heads = $html->find('thead'); 
$result = array(); 

foreach($heads as $head){ 
    $headerText = $head->find('th')[0]->innerText; 
    $result[$headerText] = array(); 
    $rows = $head->next_sibling()->find('td'); 
    foreach($rows as $row){ 
     $result[$headerText][] = $row->innerText; 
    } 
} 

//Output 
foreach($result as $header => $rows){ 
    echo $header . ': ' . implode(',', $rows); 
} 

Quelques mises en garde, ce qui précède est un simple exemple de ce que vous voulez faire. C'est une mise en œuvre assez naïve. Par exemple. il suppose qu'un thead donné aura seulement exactement 1 th.

En outre, si l'écho est vraiment tout ce que vous voulez faire, il serait plus efficace d'écho directement dans la boucle d'analyse. J'ai séparé la sortie car je suppose que vous voulez faire plus que simplement l'imprimer à l'écran. Notez, il serait assez simple de faire quelque chose comme ça en utilisant l'analyseur dom native, je suppose que vous avez besoin d'utiliser html dom simple pour une autre raison.

+0

Merci, cela a fonctionné parfaitement. La solution de @ trincot a également fonctionné. – user972391

1

Vous pouvez utiliser l'interface standard DOMDocument pour cela. Si votre code HTML est stocké dans la variable $html, puis faites:

$dom = new DOMDocument(); 
$dom->loadHTML($html); 
foreach ($dom->getElementsByTagName('tr') as $row) { 
    if ($row->parentNode->tagName === 'thead') $arr[] = []; 
    $arr[count($arr)-1][] = trim($row->textContent); 
} 

Après avoir exécuté ce qui précède, la $arr variables aura ce contenu:

[ 
    ['Header 1', 'Row 1'], 
    ['Header 2', 'Row 2', 'Row 3'], 
    ['Header 3', 'Row 4', 'Row 5', 'Row 6'] 
]