PHP Simple HTML DOM Parser: выберите только DIV с несколькими классами

Я искал как сумасшедший и не нашел решения. Проблема проста.

Скажем, у меня есть 3 DIV:

<div class="class1">
  <div class="subclass"> TEXT1 </div>
</div>

<div class="class2">
  <div class="subclass"> TEXT2 </div>
</div>

<div class="class1 class2">
  <div class="subclass"> TEXT3 </div>
</div>

Итак, очень просто. Я просто хочу найти TEXT3, который имеет ОБА class1 и class2. Используя Simple HTML DOM Parser, я не могу заставить его работать.

Вот что я пробовал:

foreach($html->find("[class=class1], [class=class2]") as $item) {
$items[] =  $item->find('.subclass', 0)->plaintext;
}

Проблема в том, что с

find("[class=class1], [class=class2]")

он находит их все, так как запятая похожа на ИЛИ, если я оставлю запятую, он ищет вложенный class2 внутри class1. Я просто ищу И...

ИЗМЕНИТЬ

Благодаря 19greg96 я узнал, что

div[class=class1 class2]

работает, проблема в том, что он ищет именно эти два в таком порядке. скажем, у меня есть

<div class="class1 class2">
  <div class="subclass"> TEXT3 </div>
</div>

тогда это работает, и если у меня есть

<div class="class1 class2 class3">
  <div class="subclass"> TEXT3 </div>
</div>

он работает, когда я ставлю звездочку, так как он ищет подстроку:

div[class*=class1 class2]

ПРОБЛЕМА

Знаю только, что класс1 и класс3 есть, но может и другие и в случайном порядке. Это все еще не работает. Любая идея, как просто искать A и B в любом случайном порядке? Так что

div[class=class1 class3]

работает с этим примером?


person Chris    schedule 10.01.2013    source источник
comment
Вам нужны конкретно элементы с .class1 и .class2 или любой элемент, который имеет 2 или более любого класса?   -  person Marc B    schedule 10.01.2013
comment
только элементы с .class1 и .class2   -  person Chris    schedule 10.01.2013
comment
отредактировано: проблема решена только частично   -  person Chris    schedule 11.01.2013


Ответы (4)


EDIT2: так как это ошибка в анализаторе dom (проверено на версия 1.5), нет простого способа сделать это. Решение, о котором я мог подумать:

$find = $html->find(".class1");
$ret = array();
foreach ($find as $element) {
    if (strpos($element->class, 'class3') !== false) {
        $ret[] = $element;
    }
}
$find = $ret;

в основном вы находите все элементы с классом один, а затем перебираете эти элементы, чтобы найти те, которые имеют класс два (в данном случае три).


Предыдущий ответ:

Простой ответ (должен работать в соответствии со спецификацией html):

find(".class1.class2")

это будет искать любой тип элемента (div, img, a и т. д.), который имеет как class1, так и class2. Если вы хотите указать тип элемента для соответствия, добавьте его в начало без ., например:

find("div.class1.class2")

Если у вас есть пробел между двумя указанными классами, он будет соответствовать элементам как с классами, так и с элементами, вложенными в элемент с первым классом:

find(".class1 .class2")

будет соответствовать

<div class="class1">
  <div class="class2">this will be returned</div>
</div>

or

<div class="class1 class2">this will be returned</div>

edit: я попробовал ваш код и обнаружил, что приведенные выше решения не работают. Однако решение, которое действительно работает, выглядит следующим образом:

$html->find("div[class=class1 class2]")
person 19greg96    schedule 10.01.2013
comment
Спасибо за ответ, но я попробовал, и он не работает ни с одним примером, .class1.class2 или div.class1.class2. Просто ничего не находит. - person Chris; 10.01.2013
comment
это очень интересно. Я попробовал код сам и получил те же результаты, что и вы. Ищем дальше. - person 19greg96; 10.01.2013
comment
Вроде нашел, но мне кажется, что то, что find(".class1.class2") не работает, может свидетельствовать о баге в парсере html. Решение, которое сработало для меня, было $html->find("div[class=class1 class2]") - person 19greg96; 10.01.2013
comment
Эй, пожалуйста, смотрите редактирование выше, кажется, есть еще одна проблема. - person Chris; 11.01.2013
comment
Обновленный ответ, где-то может быть лучший ответ, но я не смог его найти. - person 19greg96; 11.01.2013

Вы также можете попробовать это:

test.html

<h1 class="first second last">
    <p>Paragraph</p>
</h1>

Решение :

include "simple_html_dom.php";

$html = file_get_html('test.html');
$h1 = $html->find('h1');
foreach ($h1 as $h1) {
    $h1Class = ($h1->class);
    if($h1Class == 'first second last'){
        $item['test'] = 'success';
    }else{
        $item['test'] = 'fail';
    }
    $ar[] = $item;
}
echo "<pre>";
print_r($ar);
person Paramjeet    schedule 10.01.2016

$html->find(div[класс=имякласса1], div[класс=имякласса2]);

or

$html->найти(div.имякласса1, div.имякласса2);

person user1765447    schedule 02.10.2013
comment
Это то, что сработало для меня - поиск детей определенного родителя. то есть $html->find('section.whatever div.classname1, section.whatever div.classname2') - person Mr Davros; 12.02.2019

Я думал, что простой html dom позволит вам сделать:

$html->find(".class1.class2")

Но я думаю, что нет. Вы можете переключиться на эту библиотеку, если хотите.

person pguardiario    schedule 30.01.2019