Document Object Model
// same as pq(‘anything’)->htmlOuter()
// but on document root (returns doctype etc)
print phpQuery :: getDocument ();
?>
It uses DOM extension and XPath so it works only in PHP5.
If you want to use DOMDocument in your PHPUnit Tests drive on Symfony Controller (testing form)! Use like :
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use YourBundle\Controller\TextController;
class DefaultControllerTest extends WebTestCase
public function testIndex()
$client = static::createClient(array(), array());
$crawler = $client->request(‘GET’, ‘/text/add’);
$this->assertTrue($crawler->filter(«form»)->count() > 0, «Text form exist !»);
$domDocument = new \DOMDocument;
$domInput = $domDocument->createElement(‘input’);
$dom = $domDocument->appendChild($domInput);
$dom->setAttribute(‘slug’, ‘bloc’);
$formInput = new \Symfony\Component\DomCrawler\Field\InputFormField($domInput);
$form->set($formInput);
if ($client->getResponse()->isRedirect())
$crawler = $client->followRedirect(false);
>
// $this->assertTrue($client->getResponse()->isSuccessful());
//$this->assertEquals(200, $client->getResponse()->getStatusCode(),
// «Unexpected HTTP status code for GET /backoffice/login»);
When I tried to parse my XHTML Strict files with DOM extension, it couldn’t understand xhtml entities (like ©). I found post about it here (14-Jul-2005 09:05) which adviced to add resolveExternals = true, but it was very slow. There was some small note about xml catalogs but without any glue. Here it is:
XML catalogs is something like cache. Download all needed dtd’s to /etc/xml, edit file /etc/xml/catalog and add this line:
I hate DOM model !
so I wrote dom2array simple function (simple for use):
function dom2array($node) $res = array();
print $node->nodeType.’
‘;
if($node->nodeType == XML_TEXT_NODE) $res = $node->nodeValue;
>
else if($node->hasAttributes()) $attributes = $node->attributes;
if(!is_null($attributes)) $res[‘@attributes’] = array();
foreach ($attributes as $index=>$attr) $res[‘@attributes’][$attr->name] = $attr->value;
>
>
>
if($node->hasChildNodes()) $children = $node->childNodes;
for($i=0;$ilength;$i++) $child = $children->item($i);
$res[$child->nodeName] = dom2array($child);
>
>
>
return $res;
>
The project I’m currently working on uses XPaths to dynamically navigate through chunks of an XML file. I couldn’t find any PHP code on the net that would build the XPath to a node for me, so I wrote my own function. Turns out it wasn’t as hard as I thought it might be (yay recursion), though it does entail using some PHP shenanigans.
Hopefully it’ll save someone else the trouble of reinventing this wheel.
function getNodeXPath ( $node ) // REMEMBER THAT XPATHS USE BASE-1 INSTEAD OF BASE-0.
// Get the index for the current node by looping through the siblings.
$parentNode = $node -> parentNode ;
if( $parentNode != null ) $nodeIndex = 0 ;
do $testNode = $parentNode -> childNodes -> item ( $nodeIndex );
$nodeName = $testNode -> nodeName ;
$nodeIndex ++;
// PHP trickery! Here we create a counter based on the node
// name of the test node to use in the XPath.
if( !isset( $ $nodeName ) ) $ $nodeName = 1 ;
else $ $nodeName ++;
// Failsafe return value.
if( $nodeIndex > $parentNode -> childNodes -> length ) return( «/» );
> while( ! $node -> isSameNode ( $testNode ) );
// Recursively get the XPath for the parent.
return( getNodeXPath ( $parentNode ) . «/ < $node ->nodeName > [ ]» );
> else // Hit the root node! Note that the slash is added when
// building the XPath, so we return just an empty string.
return( «» );
>
>
?>
If you want to print the DOM XML file content, you can use the next code:
$doc = new DOMDocument();
$doc->load($xmlFileName);
echo «
» . $doc->documentURI;
$x = $doc->documentElement;
getNodeContent($x->childNodes, 0);
function getNodeContent($nodes, $level) foreach ($nodes AS $item) // print «
TIPO: » . $item->nodeType ;
printValues($item, $level);
if ($item->nodeType == 1) < //DOMElement
foreach ($item->attributes AS $itemAtt) printValues($itemAtt, $level+3);
>
if($item->childNodes || $item->childNodes->lenth > 0) getNodeContent($item->childNodes, $level+5);
>
>
>
>
function printValues($item, $level) if ($item->nodeType == 1) < //DOMElement
printLevel($level);
print $item->nodeName . »
«;
if ($level == 0) print «
«;
>
for($i=0; $i < $level; $i++) print "-";
>
>
As of PHP 5.1, libxml options may be set using constants rather than the use of proprietary DomDocument properties.
DomDocument->resolveExternals is equivilant to setting
LIBXML_DTDLOAD
LIBXML_DTDATTR
DomDocument->validateOnParse is equivilant to setting
LIBXML_DTDLOAD
LIBXML_DTDVALID
PHP 5.1 users are encouraged to use the new constants.
Introduction
The DOM extension allows you to operate on XML documents through the DOM API with PHP.
Note:
The DOM extension uses UTF-8 encoding. Use mb_convert_encoding() , UConverter::transcode() , or iconv() to handle other encodings.
User Contributed Notes 1 note
Be careful when using this for partial HTML. This will only take complete HTML documents with at least an HTML element and a BODY element. If you are working on partial HTML and you fill in the missing elements around it and don’t specify in META elements the character encoding then it will be treated as ISO-8859-1 and will mangle UTF-8 strings. Example:
$body = getHtmlBody ();
$doc = new DOMDocument ();
$doc -> loadHtml ( «
// $doc will treat your HTML ISO-8859-1.
// this is correct but may not be what you want if your source is UTF-8
?>
$body = getHtmlBody ();
$doc = new DOMDocument ();
$doc -> loadHtml ( «
// $doc will treat your HTML correctly as UTF-8.
?>
- DOM
- Introduction
- Installing/Configuring
- Predefined Constants
- Examples
- DOMAttr
- DOMCdataSection
- DOMCharacterData
- DOMChildNode
- DOMComment
- DOMDocument
- DOMDocumentFragment
- DOMDocumentType
- DOMElement
- DOMEntity
- DOMEntityReference
- DOMException
- DOMImplementation
- DOMNamedNodeMap
- DOMNode
- DOMNodeList
- DOMNotation
- DOMParentNode
- DOMProcessingInstruction
- DOMText
- DOMXPath
- DOM Functions
Взаимодействие PHP и XML
Для работы с XML -документами можно использовать язык PHP. В PHP для этого существует два модуля, реализующие два разных стандарта обработки XML -данных: SAX (Simple API for XML) и DOM (Document Object Model) .
Стандарт SAX (http://www.saxproject.org) не является стандартом W3C и описывает метод обработки XML -документов для получения из них данных. То есть этот метод обработки XML -документов позволит только прочитать данные из XML -документа, и не более того. Создавать и изменять XML -документы с его помощью невозможно.
SAX основан на так называемом событийном программировании . Его особенность заключается в том, что вы предоставляете парсеру XML набор собственных функций, которые будут заниматься обработкой различных типов XML -данных ( элементов (тегов), текста и т.п.), а парсер затем будет сам вызывать ваши функции в процессе обработки XML -документа, передавая им найденные данные. Функции будут вызываться в той же последовательности, в которой соответствующие данные располагаются в XML -документе.
Другим стандартом для обработки XML -данных является DOM – стандарт W3C, спецификацию которого можно найти на сайте консорциума (http://www.w3c.org/DOM). В отличие от SAX , этот метод позволяет производить любые операции с XML -данными в достаточно удобной форме – представляя XML -документ как дерево объектов.
Модуль, реализующий этот стандарт, называется DOM XML . Он не входит в основной набор модулей PHP, но может быть установлен как расширение. API этого модуля старается как можно более точно следовать стандарту DOM level 2. Кроме того, существует множество дополнительных функций. Эти функции включены для совместимости с предыдущими версиями расширения, и использовать их в новых скриптах не рекомендуется. Кроме того, у расширения DOM XML есть проблемы с русской кодировкой. Парсер обрабатывает текст только в кодировке UTF-8, поэтому текст нужно каждый раз перекодировать с помощью функции iconv . Отсюда и необходимость установки расширения iconv вместе с DOM XML .
Модуль DOM XML является мощным и удобным в использовании средством обработки XML -документов. В данной лекции мы будем рассматривать именно его.
Установка расширения DOM XML
Для того чтобы установить расширение DOM XML , нужно сделать следующее.
- В файле настроек PHP ( php.ini ) раскомментировать строку, касающуюся этого расширения ( extension=php_domxml.dll для Windows, либо extension=php_domxml.so для Linux-платформ).
- Скопировать файл расширения ( php_domxml.dll или php_domxml.so ) в папку, где находятся расширения ( extension_dir ).
- Подключить расширение iconv так же, как в пунктах выше (иногда это расширение устанавливается автоматически вместе с domxml ).
- Скопировать дополнительные библиотеки в системную папку system (Windows 98) или system32 (WindowsNT/2000/XP). В первую очередь это библиотеки libxml2 и iconv , затем libxslt , libexslt и zlib .
- Перезапустить сервер.
Следует проверить, правильно ли установлена переменная extension_dir в файле настройки php.ini . Если она не указывает на директорию, где находятся библиотеки расширений PHP, то ни одно из расширений подключить не удастся.
Чтобы проверить, установилось ли расширение, можно создать простейший скрипт, который будет выводить все настройки PHP-интерпретатора (это делает функция phpinfo() ). Другой вариант – попробовать использовать какую-нибудь функцию из данного расширения. Например, можно попробовать получить версию используемой библиотеки libxml с помощью функции domxml_version() . Но этот способ не очень хорош, поскольку расширение экспериментальное (это значит, что некоторые функции в каких-то определенных условиях могут и не работать), да и функции еще надо изучить, прежде чем их использовать.