Как преобразовать HTML-таблицу в JSON в PHP

Я пытаюсь преобразовать некоторый html в массив, а затем в строку json.

Я разрабатываю на основе этой ссылки: https://www.codeproject.com/Tips/1074174/Simple-Way-to-Convert-HTML-Table-Data-into-PHP-Arr

Это основная таблица / html, из которой я хочу преобразовать ее в JSON.

<table class = "table-list table table-responsive table-striped">
<thead>
    <tr>
        <th class = "coll-1 name">name</th>
        <th class = "coll-2">height</th>
        <th class = "coll-3">weight</th>
        <th class = "coll-date">date</th>
        <th class = "coll-4"><span class = "info">info</span></th>
        <th class = "coll-5">country</th>
    </tr>
</thead>
<tbody>
<tr>
    <td class = "coll-1 name">
        <a href = "/username/Jhon Doe/" class = "icon"><i class = "flaticon-user"></i></a>
        <a href = "/username/Jhon Doe/">Jhon Doe</a>
    </td>
    <td class = "coll-2 height">45</td>
    <td class = "coll-3 weight">50</td>
    <td class = "coll-date">9am May. 16th</td>
    <td class = "coll-4 size mob-info">abcd</td>
    <td class = "coll-5 country"><a href = "/country/CA/">CA</a></td>
</tr>
<tr>
    <td class = "coll-1 name">
        <a href = "/username/Kasim Shk/" class = "icon"><i class = "flaticon-user"></i></a>
        <a href = "/username/Kasim Shk/">Kasim Shk</a>
    </td>
    <td class = "coll-2 height">33</td>
    <td class = "coll-3 weight">54</td>
    <td class = "coll-date">Mar. 14th '18</td>
    <td class = "coll-4 size mob-info">ijkl</td>
    <td class = "coll-5 country"><a href = "/country/UAE/">UAE</a></td>
</tr>
</tbody>
</table>

Я хочу, чтобы вывод json был таким:

[
    {   
        "user_link": "/username/Jhon Doe/",
        "name": "Jhon Doe",
        "height": "45",
        "weight": "50",
        "date": "Apr. 01st '18",
        "info": "abcd",
        "country": "CA"
    },
    {   
        "user_link": "/username/Kasim Shk/",
        "name": "Kasim Shk",
        "height": "33",
        "weight": "54",
        "date": "Mar. 14th '18",
        "info": "ijkl",
        "country": "UAE"
    }
]

Это то, что я пробовал в PHP :(

Однако это не может получить ссылку пользователя, и имя в JSON неверно.

(Таблица HTML такая же, как и выше @ http://rudraproduction.in/htmltable.php)

header("Access-Control-Allow-Origin: *");                                                                            
header('Content-Type: application/json');
error_reporting(E_ERROR | E_PARSE);
$time_start = microtime(true);

$All = [];

$link       = 'http://rudraproduction.in/htmltable.php';
$jsonData   = file_get_contents($link);

//echo $jsonData;

$dom = new DOMDocument;
$dom->loadHTML($jsonData);

$tables = $dom->getElementsByTagName('table');
$tr     = $dom->getElementsByTagName('tr'); 

foreach ($tr as $element1) {        
    for ($i = 0; $i < count($element1); $i++) {

        //Not able to fetch the user's link :(

        $link       = $element1->getElementsByTagName('td')->item(0)->getElementsByTagName('a');    // To fetch user link
        $name       = $element1->getElementsByTagName('td')->item(0)->textContent;                  // To fetch name
        $height     = $element1->getElementsByTagName('td')->item(1)->textContent;                  // To fetch height
        $weight     = $element1->getElementsByTagName('td')->item(2)->textContent;                  // To fetch weight
        $date       = $element1->getElementsByTagName('td')->item(3)->textContent;                  // To fetch date
        $info       = $element1->getElementsByTagName('td')->item(4)->textContent;                  // To fetch info
        $country    = $element1->getElementsByTagName('td')->item(5)->textContent;                  // To fetch country

        array_push($All, array(
            "user_link" => $link,
            "name"      => $name,
            "height"    => $height,
            "weight"    => $weight,
            "date"      => $date,
            "info"      => $info,
            "country"   => $country
        ));
    }
}

echo json_encode($All, JSON_PRETTY_PRINT);

Вывод моего PHP-кода:

[
    {
        "user_link": "http://rudraproduction.in/htmltable.php",
        "name": null,
        "height": null,
        "weight": null,
        "date": null,
        "info": null,
        "country": null
    },
    {
        "user_link": "http://rudraproduction.in/htmltable.php",
        "name": "\r\n\t\t\r\n\t\tJhon Doe\r\n\t",
        "height": "45",
        "weight": "50",
        "date": "9am May. 16th",
        "info": "abcd",
        "country": "CA"
    },
    {
        "user_link": "http://rudraproduction.in/htmltable.php",
        "name": "\r\n\t\t\r\n\t\tKasim Shk\r\n\t",
        "height": "33",
        "weight": "54",
        "date": "Mar. 14th '18",
        "info": "ijkl",
        "country": "UAE"
    }
]

В предоставленной вами ссылке показано, как превратить таблицу в данные массива, что будет важным первым шагом. Куда вы это взяли и где столкнулись с проблемами?

dave 25.05.2018 00:51

Когда у вас есть массив с использованием кода, на который вы ссылаетесь, передайте его в json_encode(), и все готово.

Wouter van Nifterick 25.05.2018 01:16

Привет, @mickmackusa, пожалуйста, помогите мне получить правильный вывод, как я хочу :( Я опубликовал свой PHP-код и его вывод, пожалуйста, проверьте его и помогите мне.

Chauhan Ajay 25.05.2018 17:18

@ChauhanAjay, mickmackusa в настоящее время не может общаться в Stack Overflow и не сможет взаимодействовать здесь в течение 30 дней. Они попросили меня сказать вам, что они «пошалили и не могут ответить». Однако они, очевидно, очень позаботились о том, чтобы получить вам некоторую помощь, и попросили отредактировать ваш вопрос и опубликовать ответ ниже. У меня нет дополнительной информации о ситуации в целом.

Makyen 26.05.2018 05:55
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
4
6 359
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я предпочитаю использовать XPath с DomDocument из-за полезности / простоты синтаксиса. Выбирая только элементы <tr> внутри тега <tbody>, вы можете получить доступ ко всем необходимым данным.

За исключением значения href, последняя состоящая из букв подстрока в каждом значении класса <td> представляет желаемый ключ для связанного значения. Для этого я использую preg_match(), чтобы извлечь последнее «слово» в атрибуте класса.

Если $key - это name, значение атрибута href должно быть сохранено с ключом жесткого кода: user_link.

Значения даты выборки требуют некоторой подготовки, чтобы получить желаемый формат. Поскольку ваши входные данные меняются, вам может потребоваться изменить регулярное выражение, чтобы позволить strtotime() правильно обрабатывать выражение даты.

Код: (Демо)

$html = <<<HTML
<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>

<table class = "table-list table table-responsive table-striped" border = "1">
<thead>
    <tr>
        <th class = "coll-1 name">name</th>
        <th class = "coll-2">height</th>
        <th class = "coll-3">weight</th>
        <th class = "coll-date">date</th>
        <th class = "coll-4"><span class = "info">info</span></th>
        <th class = "coll-5">country</th>
    </tr>
</thead>
<tbody>
<tr>
    <td class = "coll-1 name">
        <a href = "/username/Jhon Doe/" class = "icon"><i class = "flaticon-user"></i></a>
        <a href = "/username/Jhon Doe/">Jhon Doe</a>
    </td>
    <td class = "coll-2 height">45</td>
    <td class = "coll-3 weight">50</td>
    <td class = "coll-date">9am May. 16th</td>
    <td class = "coll-4 size mob-info">abcd</td>
    <td class = "coll-5 country"><a href = "/country/CA/">CA</a></td>
</tr>
<tr>
    <td class = "coll-1 name">
        <a href = "/username/Kasim Shk/" class = "icon"><i class = "flaticon-user"></i></a>
        <a href = "/username/Kasim Shk/">Kasim Shk</a>
    </td>
    <td class = "coll-2 height">33</td>
    <td class = "coll-3 weight">54</td>
    <td class = "coll-date">Mar. 14th '18</td>
    <td class = "coll-4 size mob-info">ijkl</td>
    <td class = "coll-5 country"><a href = "/country/UAE/">UAE</a></td>
</tr>
</tbody>
</table>

</body>
</html>
HTML;

$dom = new DOMDocument;
$dom->loadHTML($html);
$xpath = new DOMXPath($dom);
foreach ($xpath->query('//tbody/tr') as $tr) {
    $tmp = []; // reset the temporary array so previous entries are removed
    foreach ($xpath->query("td[@class]", $tr) as $td) {
        $key = preg_match('~[a-z]+$~', $td->getAttribute('class'), $out) ? $out[0] : 'no_class';
        if ($key === "name") {
            $tmp['user_link'] = $xpath->query("a[@class = 'icon']", $td)[0]->getAttribute('href');
        }
        $tmp[$key] = trim($td->textContent);
    }
    $tmp['date'] = date("M. dS 'y", strtotime(preg_replace('~\.|\d+[ap]m *~', '', $tmp['date'])));
    $result[] = $tmp;
}
var_export($result);
echo "\n----\n";
echo json_encode($result);

Вывод: (в виде массива multidim, затем строка в кодировке json)

array (
  0 => 
  array (
    'user_link' => '/username/Jhon Doe/',
    'name' => 'Jhon Doe',
    'height' => '45',
    'weight' => '50',
    'date' => 'May. 16th \'18',
    'info' => 'abcd',
    'country' => 'CA',
  ),
  1 => 
  array (
    'user_link' => '/username/Kasim Shk/',
    'name' => 'Kasim Shk',
    'height' => '33',
    'weight' => '54',
    'date' => 'Jan. 01st \'70',
    'info' => 'ijkl',
    'country' => 'UAE',
  ),
)
----
[{"user_link":"/username/Jhon Doe/","name":"Jhon Doe","height":"45","weight":"50","date":"May. 16th '18","info":"abcd","country":"CA"},{"user_link":"/username/Kasim Shk/","name":"Kasim Shk","height":"33","weight":"54","date":"Jan. 01st '70","info":"ijkl","country":"UAE"}]

Другие вопросы по теме