Trabalhando com DOM e PHP (DOMDocument class)


DOM (Document Object Model)

A extensão do DOM permite trabalhar com documentos XML através do API DOM do PHP 5.

DOMDocument class

Representa um html inteiro ou documento xml, seu construtor recebe 2 parametros que são: versão do documento e codificação do documento, exemplo:

<?php
$dom = new DOMDocument('1.0', 'iso-8859-1');

Método LOAD:

Tem função de carregar o arquivo XML, exemplo:

<?php
$dom = new DOMDOcument();
$dom->load("library.xml");
$dom->loadXML($xml);

DomDocument::loadHtmlFile() and DomDocument::loadHTML()

O método loadHTML carrega o html de uma string e o método loadHtmlFile carrega o html de um arquivo.

DomDocument::save() (para um arquivo).

Salva a arvore do documento XML interna de volta no arquivo.

DomDocument::saveHTML() (para uma string).

Retorna o documento interno em uma string de html formatada, exemplo:

<?php
$doc = new DOMDocument('1.0');

$root = $doc->createElement('html');
$root = $doc->appendChild($root);

$head = $doc->createElement('head');
$head = $root->appendChild($head);

$title = $doc->createElement('title');
$title = $head->appendChild($title);

$text = $doc->createTextNode('This is the title');
$text = $title->appendChild($text);

echo $doc->saveHTML();

DomDocument::saveXML().

Retorna uma string XML em vez de um arquivo HTML ou string HTML.

DomDocument::saveHTMLFile().

Salva o documento ja em formato html.

XPath Queries

Uma das partes mais poderosas da extensão do DOM, é sua integração com XPath de fato, DOM XPath é muito mais poderoso do que o equivalente SimpleXML.

<?php
$dom = new DomDocument();
$dom->load("library.xml");
$xpath = new DomXPath($dom);
$xpath->registerNamespace("lib", "http://exemple.org/library");
$results = $xpath->query("//lib:title/text()");
foreach ($results as $book){
      echo $book->data;
}

Uma chamada para DomXpath::query() retornará um objecto DomNodeList; você pode descobrir quantos itens ele contém usando o comprimento da propriedade, e então acessar qualquer um deles com o metodo item(). você também pode iterar através da coleção inteira usando um laço foreach();

DOMNODE:

O elemento dom possui elementos(nós), os chamados nodes, esses nodes são de certa forma “as tags”. No html temos tags definidas e não criamos essas tags, pois ja existem documentadas, porem em XML definimos nossas proprias tags e essas são os nós.

DOMDocument::createElement().

Cria um novo elemento

DOMDocument::createElementNS()

Cria um novo elemento com um namespace associado

DOMDocument::createTextNode().

Adiciona texto dentro de um node, porem o texto somente será exibido caso o node seja criado.

<?php
$dom = new DOMDocument();
$dom->load("library.xml");
$book = $dom->createElement("book");
$book->setAttribute("meta:isbn", "0973589825");
$title = $dom->createElement("title");
$text = $dom->createTextNode("php|architect's Guide to PHP Design Patterns");
$title->appendChild($text);
$book->appendChild($text);
$author = $dom->createElement("pub:publisher", "Marco Tabini & Associates, Inc.");
$book->appendChild($publisher);
$dom->documentElement->appendChild($book);

DomNode::appendChild()

Cria um elemento filho. O elemento filho é aquele que ficará dentro de outro elemento, exemplo:

<?php
$doc = new DOMDocument();

$foo = $doc->createElement("foo");
$doc->appendChild($foo);

$bar = $doc->createElement("bar");
$foo->appendChild($bar);

$bazz = $doc->createElement("bazz");
$foo->appendChild($bazz);

echo $doc->saveXML();

é o mesmo que

<foo>
<bar></bar>
<bazz></bazz>
</foo>

DomNode::insertBefore()

Insere um elemento antes de um outro elemento.

DomNode::appendChild() end DomNode::insertBefore() moverá o nó para a nova localização.

Se você desejar duplicar um nó, utilize “DomNode::cloneNode()”.

Modificando Dados

<?php
$xml = <<
algum texto aqui

XML;
$dom = new DOMDocument();
$dom->loadXML($xml);
$xpath = new DomXpath($dom);
$node->data = ucwords($node->data);
echo $dom->saveXML();

Removendo Dados

Existe três tipos de dados que você pode querer remover de um documento XML: atributos, elementos e CDATA. O DOM fornece diferentes métodos para cada uma dessas tarefas:

DomNode::removeAttribute().

Remove o atributo do elemento (node).

DomNode::removeChild().

Remove o elemento filho do node especificado.

DomCharacterData::deleteData().

Remove um intervalo de caracteres de um node, esse método recebe 2 parametros:

Offset – o primeiro caractere a ser removido.

Count – o numero de caracteres que serão removidos.

Trabalhando com Namespaces:

DOM é mais do que capaz de lidar com namespaces próprios e, tipicamente, você pode, pela maior parte, ignorai-lo e passar atributos e nome de elementos com o prefix apropriado diretamente para a maioria das funções DOM.

<?php
$dom = new DOMDocument();
$node = $dom->createElement(’ns1:somenode’);
$node->setAttribute(’ns2:someattribute’, ’somevalue’);
$node2 = $dom->createElement(’ns3:anothernode’);
$node->appendChild($node2);
// Set xmlns:* attributes
$node->setAttribute(’xmlns:ns1’, ’http://example.org/ns1’);
$node->setAttribute(’xmlns:ns2’, ’http://example.org/ns2’);
$node->setAttribute(’xmlns:ns3’, ’http://example.org/ns3’);
$dom->appendChild($node);
echo $dom->saveXML();

Nos podemos tentar simplificar o uso de namespaces um pouco usando o os métodos DomDocument::createElementNS() e DomNode::setAttributeNS()

<?php
$dom = new DOMDocument();
$node = $dom->createElementNS(’http://example.org/ns1’, ’ns1:somenode’);
$node->setAttributeNS(’http://example.org/ns2’, ’ns2:someattribute’, ’somevalue’);
$node2 = $dom->createElementNS(’http://example.org/ns3’, ’ns3:anothernode’);
$node3 = $dom->createElementNS(’http://example.org/ns1’, ’ns1:someothernode’);
$node->appendChild($node2);
$node->appendChild($node3);
$dom->appendChild($node);
echo $dom->saveXML();

Interagindo com SimpleXml

Você pode importar objetos SimpleXML para usar com o DOM usando o dom_import_simplexml();

<?php
$sxml = simplexml_load_file(’library.xml’);
$node = dom_import_simplexml($sxml);
$dom = new DomDocument();
$dom->importNode($node, true);
$dom->appendChild($node);

O oposto também é possível, usando a função propriamente chamada simplexml_import_dom();

<?php
$dom = new DOMDocument();
$dom->load(’library.xml’);
$sxe = simplexml_import_dom($dom);
echo $sxe->book[0]->title;

,

  1. #1 by Ruben on 1 de novembro de 2010 - 18:05

    Muito útil a explicação.
    Parabéns

  2. #2 by Felipe on 13 de junho de 2011 - 13:12

    Belo artigo.

    não sei se você ja passou por um problema ao usar o load(),
    fiz um script e local funcionou perfeitamente, em outros servidores mesma coisa,
    mas em um servidor em especial que estou configurando o script
    (leitura e atualização de noticias com base em um feed),
    percebi que mesmo tento o Dom habilitado,
    o load não carrega os dados do XML que é uma url…

    você ja passou por isso?

    • #3 by Thiago dos Santos Valentim on 14 de junho de 2011 - 12:57

      Estranho, nunca passei por isso, vale a pena dar uma conferida no php.ini. Por se tratar de outro servidor é possivel que a compilação do php esteja diferente com relação ao DOM. Dá uma olhada na compilação do DOM, talvez ajude. O meu, por exemplo, está assim:

      dom
      DOM/XML enabled
      DOM/XML API Version 20031129
      libxml Version 2.7.7
      HTML Support enabled
      XPath Support enabled
      XPointer Support enabled
      Schema Support enabled
      RelaxNG Support enabled

(não será publicado)