Правильно распределите содержимое dom в Array с помощью XPath - PullRequest
0 голосов
/ 20 мая 2018

Пример HTML:

<div class"classX">
<a href="#" class="aClass">Link Text 1</a>
<span class="sClass"><p>Text #1</p></span>
</div>

<div class="classX">
<a href="#" class="aClass">Link Text 2</a>
</div>

<div class="classX">
<a href="#" class="aClass">Link Text 3</a>
</div>

<div class="classX">
<a href="#" class="aClass">Link Text 4</a>
<span class="sClass"><p>Text #4</p></span>
</div>

<div class="classX">
<a href="#" class="aClass">Link Text 5</a>
<span class="sClass"><p>Text #5</p></span>
</div>

Я пытаюсь создать массив, который будет выглядеть следующим образом:

 [0] => Array
        (
            [link_text] => Link Text 1
            [span_text] => Text #1
        )

    [1] => Array
        (
            [link_text] => Link Text 2
        )

    [2] => Array
        (
            [link_text] => Link Text 3
        )

    [3] => Array
        (
            [link_text] => Link Text 4
            [span_text] => Text #4
        )

    [4] => Array
        (
            [link_text] => Link Text 5
            [span_text] => Text #5
        )

Но с использованием цикла foreach со значением $keyнеправильно организовывает вывод, и вместо этого я получаю массив, который выглядит следующим образом:

 [0] => Array
        (
            [link_text] => Link Text 1
            [span_text] => Text #1
        )

    [1] => Array
        (
            [link_text] => Link Text 2
            [span_text] => Text #4
        )

    [2] => Array
        (
            [link_text] => Link Text 3
            [span_text] => Text #5
        )

    [3] => Array
        (
            [link_text] => Link Text 4
        )

    [4] => Array
        (
            [link_text] => Link Text 5
        )

Я полностью понимаю, почему это происходит, потому что я использую ключ link_text при доступе к значению span_text, ноЯ понятия не имею, как правильно построить массив с правильной комбинацией.

PHP:

$finder = new DomXPath($dom);
$link_texts= $finder->query("//a[contains(@class, normalize-space('aClass'))]");
$span_text= $finder->query("//span[contains(@class,'sClass')]/@data-html");


foreach ($link_texts as $key => $link_text) {

    if (empty($span_text[$key]->textContent)) {
        $link_text = trim($link_text->textContent);
        $dataArr[] = str_replace("\n", " ", $link_text);
        $data[] = array("link_text"=>str_replace("\n", " ", $link_text));
    } else {
        $span_text = str_replace("\n", " ", $span_text[$key]->textContent);
        $span_text = preg_replace('~</?p[^>]*>~', '', $span_text);
        $link_text = trim($link_text->textContent);
        $data[] = array("link_text"=>str_replace("\n", " ", $link_text), "span_text"=>$span_text);
    }

}

1 Ответ

0 голосов
/ 20 мая 2018

Я думаю, что было бы легче начать с выбора всех родительских <div class"classX"> элементов.Затем мы можем выбрать вложенные элементы a и span для каждого div.

$finder = new DomXPath($dom);
$divs = $finder->query("//div[@class='classX']");
$data = array();

foreach($divs as $div) {
    $link = $finder->query("./a[@class='aClass']", $div)->item(0);
    $span = $finder->query("./span[@class='sClass']", $div)->item(0);
    $items = array(
        "link_text" => $link ? $link->textContent : null, 
        "span_text" => $span ? $span->textContent : null
    );
    $data[] = array_filter($items);
}

print_r($data);

Создает массив $data со всеми элементами link_text и span_text в правильном порядке.

Нулевые значения удаляются с помощью array_filter, поэтому некоторые вложенные массивы не имеют ключа span_text.
Если требуется постоянное количество элементов, то не проговаривайте $itemsмассив.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...