Autor Zpráva
jirka2
Profil
Ahoj,
mám jednoduchý kód:
$html =<<<EOT
<html>
<body>
<h1>Zdar</h1><option value=1>leden<option value=2>unor<option value=3>brezen
</body>
</html>
EOT;

$dd = new DOMDocument;
$dd->loadHTML($html);
$xp = new DomXPath($dd);
$nodes = $xp->query("//body");
echo $nodes[0]->nodeValue;
a výstup je 'Zdarledenunorbrezen' a to není, to co chci. Rád bych aby to byly čtyři slova. Ale $xp->query("//body") nemá cenu měnit, ta struktura je ve skutečnosti komplikovanější. Prostě mě zajímají všechna (oddělená) slova v body. A nikoliv jedna nudle. Hledal jsem a nic nenašel, jde to vůbec?

díky za pomoc, Jirka
Kcko
Profil
jirka2:
<?php

$html =<<<EOT
<html>
<body>
<h1>Zdar</h1><option value=1>leden<option value=2>unor<option value=3>brezen
</body>
</html>
EOT;
 
$dd = new DOMDocument;
$dd->loadHTML($html);
$xp = new DomXPath($dd);
$nodes = $xp->query("//body/*");
$allValues = [];
foreach ($nodes as $node) {
    $allValues[] = $node->nodeValue;
}
print_r($allValues);

Btw. option tagy mají být v select tagu
jirka2
Profil
Kcko:
Geniální a jednoduché, velmi děkuji. Ono je to komplikovanější, je to mnohokráte zanořené a musel jsem to ještě upravit, viz:
$html =<<<EOT
<html>
<body>
<div><div><select><option value=1>leden<option value=2>unor<option value=3>brezen</select></div></div>
</body>
</html>
EOT;

$dd = new DOMDocument;
$dd->loadHTML($html);
$xp = new DomXPath($dd);
$nodes = $xp->query("//body//*");

foreach ($nodes as $node) {
    if ($node->childElementCount == 0) {
        $allValues[] = $node->nodeValue;
    }
}
print_r($allValues);
Pracuji jen s nody, které nemají potomky, snad je to korektní. Fakt moc díky za rady!
Kcko
Profil
jirka2:
Není zač, vycházel sem ze struktury, kterou jsi poslal, kdybys ukázal zanořeniny ;) tak bych to napsal jinak.
Jestli ti to funguje tak OK.
jirka2
Profil
jirka2:
Ale zase výše popsané řešení s potomky selže při výrazu
<div>aaa <b>BBB</b> ccc ddd <b>EEE</b> fff</div>
tam se hodí query
$nodes = $xp->query("//body");
Ale jak to udělat všechno dohromady:
$html =<<<EOT
<html>
<body>
<select><option value=1>leden<option value=2>unor<option value=3>brezen</select>
<div>aaa <b>BBB</b> ccc ddd <b>EEE</b> fff</div>
</body>
</html>
EOT;
Upozorňuji, že to může být různě zanořené. A potřebuji z toho dostat jednotlivá slova, nejlépe jedním query.
Kajman
Profil
Zkuste //body//*/text()
jirka2
Profil
Kajman:
To je ideální, velmi děkuji za radu.
jirka2
Profil
Tak jsem tu zas, není to tak ideální, jak jsem si myslel. Selže to pokud je samotný text v hned v body:
$html =<<<EOT
<html>
<body>
<select><option value=1>leden<option value=2>unor<option value=3>brezen</select>
<div>aaa <b>BBB</b> ccc ddd <b>EEE</b> fff</div>
xxx <b>yyy</b> zzz
</body>
</html>
EOT;
//body//*/text() nalezne jen yyy. Zvládne to //body[text()], ale ten zase spojí ty měsíce: ledenunorbrezen
Prostě nemohu najít, jak vyparsovat všechna slova z body. Přitom nemusí být každé zvlášť, stačí i jen oddělené mezerou v jednom stringu.


jirka2:
Možná by to šlo takto: //body//*/text()|//body/text()
anonym_
Profil *
jirka2:
Potřebuješ s tím dal pracovat jako s nody, s DOMem atd.? Jestli ne, tak regularem nahradit všechny tagy za mezeru a pak případně více whitespaců za jednu mezeru.

Záměrně nepíšu strip_tags, to by ti zahodilo mezery mezi slovy.
jirka2
Profil
anonym:
Díky za inspiraci, napsal jsem toto:
$body = preg_replace('/<body\s*[^>]>(.+)<\/body>/', '\1', $html);
$content = preg_replace('/<[^>]*>/', ' ', $body);
$content = preg_replace('/\s+/', ' ', $content);
echo $content;
A zdá se, že to stačí!
jirka2
Profil
jirka2:
Ten první řádek je špatně, oprava:
preg_match('/<body\s?[^>]*>(.*?)<\/body>/s', $html, $match);
Keeehi
Profil
Regulární výraz ti bude fungovat do té doby, než ti jednoho dne fungovat přestane. Ještě možná, pokud máš nad vstupem kontrolu ale to se mi nezdá, že by byl tvůj případ. Problém je, že veškeré aspekty HTML se nedají popsat regulárním výrazem. Tudíž můžeš obdržet klidně i validní HTML na které ti tvůj výraz platit nebude.
Například v tomhle <textarea>leden < únor </textarea> ti to požere únor.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0