Sparrow
Новичок
DOM в php 5. Помогите найти ошибку
Суть проблемы:
На входе есть non-well-formed html, порожденный визуальным редактором.
Требуется преобразовать его в формат NITF, а именно:
1. убрать все <br>, вместо них использовать форматирование параграфами
2. заменить все конструкции <img src="file.jpg"> на <media type="image">
Для решения используется класс, реализованный с помощью PHP 5 и библиотеки DOM.
Полный код парсера приведен в конце
Проблема возникает в ситуации, когда после обработки "запрещенного" тега i происходит переход к вложенному в него тексту. При присвоении $obElement=$obElement->firstChild методы и свойства $obElement становятся недоступны.
причем $this->DebugNode($firstChild) выдает правильную информацию, а $this->DebugNode($obElement) - нет.
Вывод вот этого куска кода:
Подскажите, где тут грабли
Версия php: 5.2.6
Версия Apache: 1.3.41, работает в режиме модуля Apache
Суть проблемы:
На входе есть non-well-formed html, порожденный визуальным редактором.
Требуется преобразовать его в формат NITF, а именно:
1. убрать все <br>, вместо них использовать форматирование параграфами
2. заменить все конструкции <img src="file.jpg"> на <media type="image">
Для решения используется класс, реализованный с помощью PHP 5 и библиотеки DOM.
Полный код парсера приведен в конце
Проблема возникает в ситуации, когда после обработки "запрещенного" тега i происходит переход к вложенному в него тексту. При присвоении $obElement=$obElement->firstChild методы и свойства $obElement становятся недоступны.
причем $this->DebugNode($firstChild) выдает правильную информацию, а $this->DebugNode($obElement) - нет.
Вывод вот этого куска кода:
PHP:
echo "First child:".$this->DebugNode($firstChild);
echo "Real first child:".$this->DebugNode($obElement->firstChild);
$obElement = $obElement->firstChild;
var_dump($obElement);
echo "Final first child:".$this->DebugNode($obElement);
Final first child: должно быть то эже, что и в First ChildFirst child:TAG=#text, TYPE=3, value=Традиционно Topman выпускает как классические вещи, так и неформальные.
Real first child:TAG=#text, TYPE=3, value=Традиционно Topman выпускает как классические вещи, так и неформальные.
object(DOMText)#40 (0) { } Final first child:TAG=, TYPE=, value=
Подскажите, где тут грабли
PHP:
private function DebugNode($obElement)
{
if ($obElement == null)
return 'NULL';
elseif ($obElement instanceof DOMNode)
return "TAG=".$obElement->nodeName.", TYPE=".$obElement->nodeType. ", value=".$this->toSiteEncoding($obElement->nodeValue)."<br/>";
else
return "Not a DOMNode or its descendant type";
}
Версия Apache: 1.3.41, работает в режиме модуля Apache
PHP:
public function convertDetailText()
{
if ($this->isDocLoaded) /* Документ загружен методом loadHtml в $this->obDocument, при этомне возникло Exception */
{
// replace 'br' with 'p'
$obBodyNodeList = $this->obDocument->GetElementsByTagName('body');
$obBodyElement = $obBodyNodeList->item(0);
// recursive walk
try {
//echo "walk";
$obElement = $obBodyElement->firstChild;
$obCurrentParagraph = $this->obDocument->CreateElement('p');
//echo "sw";
while(!$obBodyElement->isSameNode($obElement))
{
echo "initial dump: ";
var_dump($obElement);
print_r($obElement);
echo "<br/><br/>";
$bContinue = false;
//echo "inw";
echo $this->DebugNode($obElement);
//echo "dbg";
// save, as these may change thru' our actions
$nextSibling = $obElement->nextSibling;
$firstChild = $obElement->hasChildNodes() ? $obElement->firstChild : null;
$parent = $obElement->parentNode;
switch($obElement->nodeName)
{
case 'br':
echo "Removing the break...";
// remove the break
if ($parent != null)
$parent->removeChild($obElement);
// complete current paragraph
$obBodyElement->appendChild($obCurrentParagraph);
// start a new paragraph
$obCurrentParagraph = $this->obDocument->CreateElement('p');
echo "done<br/>";
break;
case 'b': // add more unwanted tags to the list here
case 'i':
case 'u':
case 'strong':
case 'em':
case 'a':
// remove a tag that is not allowed
if ($parent != null)
{
echo "Removing the violating node: <".$obElement->nodeName.'>';
$parent->removeChild($obElement);
$returnToParent = $parent;
echo "done<br/>";
}
break;
case 'img':
echo "Image conversion<br/>";
// convert image
$obConvertedNode = $this->convertImgNode($obElement);
// remove img tag
if ($parent != null)
$parent->removeChild($obElement);
// end current paragraph
$obBodyElement->appendChild($obCurrentParagraph);
// append the 'media' tag after it
$obBodyElement->appendChild($obConvertedNode);
// start a new paragraph
$obCurrentParagraph = $this->obDocument->createElement('p');
break;
default:
// add the element to the current paragraph
if ($parent != null)
$parent->removeChild($obElement);
$obCurrentParagraph->appendChild($obElement);
echo "appended to the current paragraph<br/>";
} // switch
if ($bContinue)
continue;
// goto next element in the tree;
if($obElement->nodeType == XML_TEXT_NODE)
{
echo "This is a text node";
}
if (($firstChild !== null) && ($obElement->nodeType == XML_ELEMENT_NODE))
{
// no children accepted from text nodes, etc
echo "Moving to first child<br/>";
echo "First child:".$this->DebugNode($firstChild);
echo "Real first child:".$this->DebugNode($obElement->firstChild);
$obElement = $obElement->firstChild;
var_dump($obElement);
echo "Final first child:".$this->DebugNode($obElement);
}
elseif ($nextSibling !== null)
{
echo "Moving to next sibling<br/>";
$obElement = $nextSibling;
}
else {
echo "returning to the parent<br/>";
// complete current paragraph
$this->DebugNode($obElement);
$obCurrentParagraph->appendChild($obElement);
$obBodyElement->appendChild($obCurrentParagraph);
if ($parent != null)
$obElement = $parent;
else
$obElement = $returnToParent;
// close paragraph
}
} // while
echo "end while<br/>";
// complete the last paragraph
} // try
catch (Exception $e)
{
echo "Exception caught on BR-remove: [".$e->code . '] '. $e->getMessage() . ' executing ' . $e->getFile() .'@' . $e->getLine() . '<br/>' . $e->getTraceAsString();
return false;
}
//return result
return true;
}
else // not ok
{
return false;
}
}