DOM, xml, html

Sparrow

Новичок
DOM, xml, html

Уважаемые коллеги, просьба помочь разобраться с решением следующей задачи.

Дано: есть документ (на самом деле их много, но они однотипны) в html, не вполне well-formed, но Mozilla Firefox в DOM Inspector'е ничего фатального не обнаруживает.

Надо: 1. вырезать оттуда кусок html, начиная с определенного тега и заканчивая его окончанием. Например:

PHP:
<html>.... 
   <body>
        ....
        <td class="normal">
            <!-- Вот отсюда нужно начинать копировать -->
             <table width="100%" ... >
                   ....
             </table>
             <!-- А здесь - конец -->
         </td>
    </body>
</html>
2. Преобразовать все ссылки в этом коде

Пытаюсь для этого использовать следующий код (php 5.1):
(Функция ShowMessage - для вывода результатов в лог-файл, второй параметр - для фильтра вывода, сейчас выводится все).

PHP:
function parse_ip_html($sBuffer)
{
	ShowMessage("\nSource data: $sBuffer\n", 7);
	ShowMessage("Using DOM 2 Parser\n", 5);

	// create the DOM object
	$obDocument = new DOMDocument('1.0', 'iso-8859-1');
	if (!$obDocument->loadHTML($sBuffer))
	{
		ShowMessage(" Failed to initialize DOM\n", 5);
		return false;
	}
	else
	{
		ShowMessage("\nxml tree: \n\n ". $obDocument->saveXML() . "\n\n", 7);
	}

	// look for the 'root' node
	ShowMessage("scanning for the right node...", 6);
	if(!$obNodeList = $obDocument->getElementsByTagName('td'))
	{
		ShowMessage("Failed to parse current document\n\n", 0);
		exit;
	}


	foreach($obNodeList as $obNode)
	{
		if ($obNode->hasAttributes() && $obNode->hasChildNodes())
		{
			//ShowMessage("found node: ". $obNode->tagName, 6);
			if ($obNode->getAttribute('class') == 'normal')
			{
				ShowMessage("Found.", 6);
				// get the inner table
				$arChildren = $obNode->childNodes;
				foreach($arChildren as $obChildNode)
				{
					ShowMessage("tag name: " . $obChildNode->tagName. ", ", 7);
					if ($obChildNode->tagName == 'table')
					{	
						$bFound = true;
						break;
					}
				}
				ShowMessage($bFound, 7);

				if ($bFound)
				{
					try {
						$obNewDocument = new DOMDocument('1.0', 'iso-8859-1');
						$obNewDocument->importNode($obChildNode, true);
					}
					catch (Exception $ex)
					{
						ShowMessage("Exception caught: ".$ex->getMessage()."\n", 1);
						exit();
					}	
					ShowMessage("Current subtree: \n=====================\n".$obNewDocument->saveXML()."\n\n", 7);
					exit;
					ShowMessage("Converting links... ", 6);
					// process links here
					/*
					$obLinkList = $obNewDocument->getElementsByTagName('a');
					foreach($obLinkList as $obLink)
					{
						if($obLink->hasAttribute('href'))
						{
							$url = $obLink->getAttribute('href');
							$newurl = convert_ip_link($url);
							$obLink->setAttribute('href', $newUrl);
						}
						// else it is an anchor, continue
					}
					*/
					ShowMessage("done.\n", 6);
					ShowMessage("Current subtree: \n=====================\n".$obNewDocument->saveXML()."\n\n", 7);
					// convert images
					return $obNewDocument->saveHTML();
				}
					
			}
		}
	}
	ShowMessage('This document is empty', 3);
	return false;
Проблема: если я использую importNode, то выводится пустой контент вместо html. Если appendChild, то вываливается exception. Исходный html парсится, (проверено выводом этого дела в лог) правда с кучей warning'ов (в основном по поводу того, что используется '&' в явном виде, а не '& amp;'. Проблемы начинаются именно тогда, когда я пытаюсь преобразовать найденный узел в документ и сохранить его.

Подскажите, где тут собака зарыта.

-~{}~ 28.04.06 12:28:

Однако решение нашел в соседней цепочке:
PHP:
$obNewDocument->appendChild($obNewDocument->importNode($obChildNode->cloneNode(true), true));
 

Sparrow

Новичок
Пробовал, не за что зацепиться ему. html очень рыхлый, и нет гарантии, что все теги внутри закрыты. На отладку такого уйдет гораздо больше времени.
 

nimistar

Новичок
return $obNewDocument->saveHTML();


а у тя этот выброс номано работает ??? кодировка не умирает ?
 

Sparrow

Новичок
А там кодировка iso-8859-1 в оригинале, поэтому умирать нечему. Вышеуказанный код с минимальными изменениями работает.
 

nimistar

Новичок
мдя повезло.... у мну 1251 ... на выходе бня ... может подскажешь как боротся ?
 

slach

Новичок
nimistar $dom->encoding='windows-1251';

после loadHTML
и тогда saveXML\saveHTML будет тебе в нормальной кодировке
 

nimistar

Новичок
http://phpclub.ru/talk/showthread.php?s=&postid=618663#post618663

там в триде более детально описанно! :)

естественно при любом обращении к ДОМ я пытаюсь удержать кодировку .... тщетно !
мне кажется что дело в преобразованиях ....
тоесть надо скормить ему в определенном виде кирилицу и тогда схавает .... а то очень похоже что при передаче 1251 уходит в ИСО без сдвига на локаль .... отчего и битость ....

самое ужасное что у меня на входе ХМЛ ... и его простым сдвигом нельзя прекодировать .... иконв преобразования несрабатывают также .... ибо что-то типа сдвига .....

думал это иза машины .... но нет ... пробовал на четырех разных серверах в разных комбинациях ... неужто никто не сталкивался

гляньте плз ветку приведенную выше ... может поможите ?
 
Сверху