Intereting Posts
Сообщение: Неопределенное свойство: Сайт :: $ Site_model – CodeIgniter Интеграция поисковой системы Sphider на веб-сайт Как отобразить загрузочное изображение gif или сообщение, когда PHP выполняет пакетный файл? PHP – while loop (! Feof ()) не выводит / показывает все Как заставить Doctrine обновить поля типа массива? AES-256 CBC шифрует в php и расшифровывает на Java или наоборот Установите PHP gnupg с помощью PECL на MAC / MAMP 10.8.4 PHP Неустранимая ошибка: класс 'Dotenv' не найден в ODBC и SQL Server 2008: не можете использовать подготовленные заявления? Как использовать один и тот же пароль для java и php? PHP – слой абстракции DB использует статический класс vs singleton object? Перенаправление на предыдущую страницу после входа? PHP Загружайте видео на мой канал Youtube без аутентификации пользователей с помощью YoutubeApi v3 и ouath2 PHP MySQLI Запретить SQL Injection Поиск CSS в папке с использованием PHP и изменение значений css

Traverse DOM находит id назад

Я не могу понять, как решить эту проблему.

<div> <p id="p1"> Price is <span>$ 25</span></p> <p id='p2'> But this price is $ <span id="s1">50,23</span> </p> <p id='p3'> This one : $ 14540.12 dollar</p> </div> 

То, что я пытаюсь сделать, это найти элемент с ценой в нем, и это самый короткий путь к нему. Это то, что у меня есть.

 $elements = $dom->getElementsByTagName('*'); foreach($elements as $child) { if (preg_match("/.$regex./",$child->nodeValue)){ echo $child->getNodePath(). "<br />"; } } 

Это приводит к

 /html /html/body /html/body/div /html/body/div/p[1] /html/body/div/p[1]/span /html/body/div/p[2] /html/body/div/p[2]/span /html/body/div/p[3] 

Это пути к элементам, которые я хочу, так что это нормально в этом тестовом HTML. Но на реальных веб-страницах этот путь очень длинный и подвержен ошибкам. То, что я хотел бы сделать, это найти ближайший элемент с атрибутом идентификатора и обратиться к нему.

Итак, однажды найденный элемент и элемент, сопоставляемый с $ regex, мне нужно пропустить DOM и найти первый элемент с атрибутом ID и создать новый более короткий путь. В приведенном выше примере HTML есть 3 цены, соответствующие $ regex. Цены указаны в:

 //p[@id="p1"]/span //p[@id="s1"] //p[@id="p3"] 

Вот что я хотел бы вернуть из своей функции. Я также должен избавиться от всех других существующих путей, потому что они не содержат $ regex

Любая помощь по этому поводу?

Вы можете использовать XPath для отслеживания пути предка к первому узлу, содержащему атрибут @id а затем отключить его путь. Не очистил код, но что-то вроде этого:

 // snip $xpath = new DomXPath($doc); foreach($elements as $child) { $textValue = ''; foreach ($xpath->query('text()', $child) as $text) $textValue .= $text->nodeValue; if (preg_match("/.$regex./", $textValue)) { $path = $child->getNodePath(); $id = $xpath->query('ancestor-or-self::*[@id][1]', $child)->item(0); $idpath = ''; if ($id) { $idpath = $id->getNodePath(); $path = '//'.$id->nodeName.'[@id="'.$id->attributes->getNamedItem('id')->value.'"]'.substr($path, strlen($idpath)); } echo $path."\n"; } } 

Печатать что-то вроде

 /html /html/body /html/body/div //p[@id="p1"] //p[@id="p1"]/span //p[@id="p2"] //span[@id="s1"] //p[@id="p3"]