PHP DOM Поиск в HTML и указание расположения IMG в P - PullRequest
1 голос
/ 13 февраля 2012

Я хочу разобрать какой-то HTML-код, отправленный ckeditor.HTML-код, который публикуется, выглядит следующим образом:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">#012<html><body><p>Text Before <img alt="HAMBURGER" height="20" src="/sites/all/modules/ckeditor/plugins/apoji/images/emoji-E120.png" title="HAMBURGER" width="20"> Text After</p></body></html>

(отформатирован, не требуя соответствия):

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
    <body>
        <p>
            Text Before
            <img alt="HAMBURGER" height="20" src="/sites/all/modules/ckeditor/plugins/apoji/images/emoji-E120.png" title="HAMBURGER" width="20">
            Text After
        </p>
    </body>
</html>

Я искал использовать что-то вроде следующего:

$DOM = new DOMDocument;
$DOM->loadHTML($input);

$items = $DOM->getElementsByTagName('*');
foreach ($items as $item) {
    switch ($item->nodeName) {
    case "p":
        $sms .= $item->nodeValue."\n";
        break;
    case "img":
        $img_out .= "IMG Attr: ".$item->getAttribute('title')."\n";
        break;
    }
}

Моя цель - создать простую текстовую строку, заменив изображение на основе его заголовка, поэтому у меня будет такая строка:

Text Before HAMBURGER Text After

Я начал спускатьсяМаршрут DOM, как кажется, лучший способ сделать это, но теперь у меня есть два вопроса:

  1. Если я зациклюсь на документе, как указано выше, IMG заканчивается ПОСЛЕ текста, а не в серединеЭто.Как можно избежать этого?
  2. Лучший способ извлечь весь простой текст из документа DOM, сохраняя порядок элементов (связанный с пунктом 1).

Заранее спасиболюбому, кто может внести свой вклад в это.

Ответы [ 3 ]

2 голосов
/ 13 февраля 2012

Моя цель - создать текстовую строку, заменив изображение на основе его заголовка, поэтому у меня будет такая строка:

Text Before HAMBURGER Text After

Можно использоватьзапрос XPath, чтобы выбрать нужный текст / заголовки и вывести их соответствующие значения.

$html = '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"><html><body><p>Text Before<img alt="HAMBURGER" height="20" src="/sites/all/modules/ckeditor/plugins/apoji/images/emoji-E120.png" title="HAMBURGER" width="20">Text After</p></body></html>';

$doc = new DOMDocument;
$doc->loadHTML($html);

$xpath = new DOMXPath($doc);
$nodes = $xpath->query('/html/body//text() | /html/body//img/@title');

$text = '';
foreach ($nodes as $node) {
    $text .= $node->nodeValue . ' ';
}

echo $text; // Text Before HAMBURGER Text After 
1 голос
/ 13 февраля 2012

Вы можете использовать XPath , чтобы найти определенные элементы, а затем заменить их новыми узлами.

Например,

<?php
foreach( range(0,2) as $i ) {
    $doc = new DOMDocument;
    $doc->loadhtml( getData($i) );
    foo($doc);
}


function foo(DOMDocument $doc) {
    $xpath = new DOMXPath($doc);
    foreach( $xpath->query('//p/img') as $img ) {
        $alt = $img->getAttribute('alt');

        $img->parentNode->replaceChild(
            $doc->createTextNode($alt),
            $img
        );
    }
    echo "\n---\n", $doc->savehtml(), "\n---\n";
}



function getData($i) {
    $rv = null;
    switch($i) {
        case 0; $rv = '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"><html><body><p>Text Before <img alt="HAMBURGER" height="20" src="/sites/all/modules/ckeditor/plugins/apoji/images/emoji-E120.png" title="HAMBURGER" width="20"> Text After</p></body></html>'; break;
        case 1; $rv = '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
            <html>
                <body>
                    <p>
                        Text Before <img alt="HAMBURGER" height="20" src="/sites/all/modules/ckeditor/plugins/apoji/images/emoji-E120.png" title="HAMBURGER" width="20">
                        Text After
                    </p>
                </body>
            </html>';
            break;
        case 2; $rv = '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
            <html>
                <body>
                    <p>
                        Text Before <img alt="HAMBURGER" height="20" src="/sites/all/modules/ckeditor/plugins/apoji/images/emoji-E120.png" title="HAMBURGER" width="20">
                        Text After
                    </p>
                    <p>
                        Text Before <img alt="HAMBURGER2" height="20" src="/sites/all/modules/ckeditor/plugins/apoji/images/emoji-E120.png" title="HAMBURGER" width="20">
                        Text After
                    </p>
                    <p>
                        Text Before <img alt="HAMBURGER3" height="20" src="/sites/all/modules/ckeditor/plugins/apoji/images/emoji-E120.png" title="HAMBURGER" width="20">
                        Text After
                    </p>
                </body>
            </html>';
            break;
    }   
    return $rv; 
}

печать

---
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body><p>Text Before HAMBURGER Text After</p></body></html>

---

---
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body>
                    <p>
                        Text Before HAMBURGER
                        Text After
                    </p>
                </body></html>

---

---
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body>
                    <p>
                        Text Before HAMBURGER
                        Text After
                    </p>
                    <p>
                        Text Before HAMBURGER2
                        Text After
                    </p>
                    <p>
                        Text Before HAMBURGER3
                        Text After
                    </p>
                </body></html>

---

По вашему вопросу № 2: пожалуйста, уточните.Может быть так просто, как echo $doc->documentElement->textContent.Но может также закончиться использованием XSL (T)

0 голосов
/ 13 февраля 2012

Вы можете просто использовать замену регулярного выражения:

<?php
$text = "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\">#012<html><body><p>Text Before <img alt=\"HAMBURGER\" height=\"20\" src=\"/sites/all/modules/ckeditor/plugins/apoji/images/emoji-E120.png\" title=\"HAMBURGER\" width=\"20\"> Text After</p></body></html>";
$match = array();
preg_match("/<p[^>]*>(.*(?=<\/p))/i", $text, $match);
echo preg_replace("/<img[^>]*title=\"([^\"]+)\"[^>]*>/i", "$1", $match[1]);
?>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...