Wstęp.
Czekałeś na kolejną część podążania mrocznymi, albo może już teraz jasnymi, ścieżkami XPath? Już nie musisz się nudzić. Dziś kolejna porcja praktycznych przykładów.
Scena pierwsza: "Usuniecie klas i styli inline ze wszystkich elementów".
$elements = $xpath->query('//*[@class or @style]');
foreach($elements as $element){
$element->removeAttribute('class');
$element->removeAttribute('style');
}
echo $dom->saveHTML();
W zapytaniu XPath wybieramy wszystkie elementy w hierarchii drzewa DOM z atrybutem class lub style.
Scena druga: "Usuwanie pustych paragrafów".
Za puste paragrafy uznamy tagi P, które zawierają pusty ciąg znaków, dowolną liczbę spacji lub znaków , lub kombinację dwóch ostatnich.
<!DOCTYPE html>
<html>
<body>
<p></p>
<p>Tu jest jakiś tekst</p>
<p> </p>
<p> </p>
<p> </p>
<p>Tu jest jakiś drugi tekst</p>
<p> </p>
</body>
</html>
+
$empties = $xpath->query('//p[normalize-space(translate(text()," ",""))=""]');
foreach($empties as $empty){
$empty->parentNode->removeChild($empty);
}
echo $dom->saveHTML();
Po znalezieniu paragrafów spełniających kryteria usuwamy każdy z nich poprzez wywołanie metody removeChild na rodzicu. Ale co się dzieje w zapytaniu XPath?
Funkcja translate działa jak replace, czyli zamienia w podanym jako pierwszy argument ciągu zadany ciąg (drugi argument) na inny ciąg (trzeci argument). A co robi normalize-space? Usuwa białe znaki z początku i końca ciągu. Teraz możesz sobie zadać pytanie po co więc dwie funkcje, gdzie jedna z nich usuwa spacje (bo przecież jest tam " "), a druga na nią nałożona.... usuwa spacje.
Pamiętajmy, że mamy jeszcze , który nie jest białym znakiem. Jego pozbywamy się właśnie poprzez funkcję translate, przy czym niestety w DOMXPath nie możemy posługiwać się encjami HTML-owymi, więc wstukana jest tam twarda spacja przy pomocy ALT+0160 (0160 z klawiatury numerycznej). Kiedy więc pozbędziemy się , można z pełną premedytacją zająć się usuwaniem miękiszonów przy pomocy normalize-space. Po takiej operacji szukamy paragrafów z pustym ciągiem znaków.
Wynik będzie następujący:
<!DOCTYPE html>
<html>
<body>
<p>Tu jest jakiś tekst</p>
<p>Tu jest jakiś drugi tekst</p>
</body>
</html>
Scena trzecia: "Zamiana tagu IMG w PICTURE".
Ponieważ responsywność opanowała świat stron internetowych możesz sobie nieco uprościć pisaniego kodu HTML. Wystarczy, że wstawisz tag IMG, a ten kod automatycznie zmieni go na PICTURE ze źródłami przystosowanymi do różnych rozdzielczości. No, może nie tak do końca, bo musiałbyś sam zadbać jakie alternatywne źródła podstawiać dla konkretnego obrazka na stronie. W tym przykładzie dodajemy "na sztywno" alternatywne źródła. Jak zuniwersalizować kod - pozostawiam Tobie.
<!DOCTYPE html>
<html>
<body>
<img src="oryginal.jpg" alt="Obrazek"/>
</body>
</html>
+
$dom = new IvoPetkov\HTML5DOMDocument(); // wyjątkowo używamy klasy do obsługi HTML5
$dom->loadHTML($html);
$xpath = new DOMXPath($dom);
$imgs= $xpath->query('//img');
foreach($imgs as $img){
$parent = $img->parentNode; /* zapamiętujemy rodzica <IMG> */
$picture = $dom->createElement('picture'); /* tworzymy element <PICTURE> */
$source = $dom->createElement('source'); /* tworzymy element <SOURCE> */
$source->setAttribute('srcset', 'maly.jpg'); /* ustawiamy źródło */
$source->setAttribute('media', '(max-width: 320px)'); /* które będzie obowiązywać do 320px szerokości */
$picture->appendChild($source);
$source = $dom->createElement('source');
$source->setAttribute('srcset', 'sredni.jpg');
$source->setAttribute('media', '(max-width: 640px)');
$picture->appendChild($source);
$source = $dom->createElement('source');
$source->setAttribute('srcset', 'duzy.jpg');
$source->setAttribute('media', '(max-width: 960px)');
$picture->appendChild($source);
$picture->appendChild($img); /* wstawiamy <IMG> do <PICTURE> - oryginał zmienia miejsce */
$parent->appendChild($picture); /* dodajemy do rodzica <PICTURE> */
}
echo $dom->saveHTML();
Zakończenie.
Choć z każdym odcinkiem odwiedzamy coraz to nowsze lokalizacje, nie rozpakowywuj plecaka. Jeszcze czeka nas trochę łażenia.
Przydatne linki:
"The tag is out there", czyli DOMXPath S01E01
"The tag is out there", czyli DOMXPath S01E02
HTML5DOMDocument by Ivo Petkov