Как мне разобрать частичный HTML? - PullRequest
16 голосов
/ 19 декабря 2009

Я пытаюсь проанализировать HTML с DOM в PHP, но у меня возникли некоторые проблемы. Во-первых, в случае, если это изменит решение, у меня есть не полная страница HTML, а лишь ее часть.

<!-- This is the HTML that I have --><a href='/games/'>
<div id='game'>
<img src='http://images.example.com/games.gif' width='300' height='137' border='0'>
<br><b> Game </b>
</div>
<div id='double'>
<img src='http://images.example.com/double.gif' width='300' height='27' border='0' alt='' title=''>
</div>
</a>

Теперь я пытаюсь получить только div с идентификатором double. Я пробовал следующий код, но он не работает должным образом. Что я могу делать не так?

//The HTML has been loaded into the variable $html
$dom=new domDocument;
$dom->loadHTML($html);
$dom->preserveWhiteSpace = false; 
$keepme = $dom->getElementById('double'); 

$contents = '<div style="text-align:center">'.$keepme.'</a></div>';
echo $contents;

Ответы [ 5 ]

13 голосов
/ 19 декабря 2009

Я думаю DOMDocument::getElementById не будет работать в вашем случае: (цитирование)

Чтобы эта функция работала, вы будете нужно либо установить некоторые атрибуты идентификатора с DOMElement::setIdAttribute или DTD, который определяет атрибут типа ID.
В последнем случае вы нужно будет проверить ваш документ с DOMDocument::validate или DOMDocument->validateOnParse до используя эту функцию.


Решение, которое может сработать, - это использовать запрос XPath для извлечения искомого элемента.

Прежде всего, давайте загрузим часть HTML, как вы это сделали вначале:

$dom=new domDocument;
$dom->loadHTML($html);
var_dump($dom->saveHTML());

var_dump здесь только для того, чтобы доказать, что часть HTML была успешно загружена - судя по ее выводу, она имеет.


Затем создайте экземпляр класса DOMXPath и используйте его для запроса элемента, который вы хотите получить:

$xpath = new DOMXpath($dom);
$result = $xpath->query("//*[@id = 'double']");
$keepme = $result->item(0);

Теперь нам нужно элемент, который вы хотите; -)


Но для того, чтобы внедрить его HTML-контент в другой HTML-сегмент, мы должны сначала получить его HTML-контент.

Я не помню ни одного "легкого" способа сделать это, но что-то вроде этого могло бы помочь:

$tempDom = new DOMDocument();
$tempImported = $tempDom->importNode($keepme, true);
$tempDom->appendChild($tempImported);
$newHtml = $tempDom->saveHTML();
var_dump($newHtml);

И ... У нас есть содержимое HTML вашего double <div>:

string '<div id="double">
<img src="http://images.example.com/double.gif" width="300" height="27" border="0" alt="" title="">
</div>
' (length=125)


Теперь вам просто нужно делать с ней все, что вы хотите; -)

3 голосов
/ 19 декабря 2009

С DomDocument::getElementById

Чтобы эта функция работала, вы будете нужно либо установить некоторые атрибуты идентификатора с DOMElement :: setIdAttribute или DTD, который определяет атрибут типа ID. В последнем случае вы нужно будет проверить ваш документ с DOMDocument :: проверить или DOMDocument-> validateOnParse before используя эту функцию.

Для дополнительной информации

И так как кто-то упомянул, что рано или поздно он делал это с Регулярным выражением, вот шаблон, который вы можете использовать: /<div id='double'>(.*)<\/div>/simU

Кроме того, вы можете просто использовать обычные строковые функции для извлечения части div, например,

$div = strstr($html, '<div id="double">');
$div = substr($div, 0, strpos($div, '</div>') + 6);
echo $div;

Хотя я согласен, вы не должны использовать функции RegEx или String для разбора HTML или XML, но я считаю, что это вполне нормально, , пока ваша единственная задача - получить этот единственный Div от фрагментов. Сохраняй это простым.

0 голосов
/ 19 декабря 2009

Фрагмент - это HTML, но для анализа через DOM он должен быть XHTML. Каждый открытый тег должен быть закрыт.

В вашем случае это означает, что вы должны заменить <br> на <br /> и <img ... > на <img ... />

0 голосов
/ 19 декабря 2009

XML-документ может иметь только один элемент на корневом уровне. Вероятно, HTML-парсер имеет аналогичное требование. Попробуйте обернуть содержимое в тег <body/>.

Кажется, это что-то еще. Эта страница описывает причину. Я бы порекомендовал использовать XPath для получения элемента.

0 голосов
/ 19 декабря 2009

HTML Tidy должен уметь «исправлять» разбитые и фрагментированные документы HTML, превращая их во что-то, что можно анализировать с помощью других инструментов

http://devzone.zend.com/article/761

Расширение Tidy является новым в PHP 5, и доступен из версии PHP 5.0b3 вверх. Он основан на библиотеке TidyLib и позволяет Разработчик для проверки, ремонта и разбирать документы HTML, XHTML и XML из PHP.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...