PHP-DOM La clase DOMDocument
Tal como dijimos en manipulando el DOM la clase DOMDocument representará un documento HTML o XML y sirve como raíz del documento.
Para empezar a trabajar con el DOM con PHP deberás crear un nuevo objeto DOMDocument.
El siguiente código fue sacado de php.net este muestra las propiedades y métodos de DomDocument
class DOMDocument extends DOMNode { /* Propiedades */ readonly public string $actualEncoding; readonly public DOMConfiguration $config; readonly public DOMDocumentType $doctype; readonly public DOMElement $documentElement; public string $documentURI; public string $encoding; public bool $formatOutput; readonly public DOMImplementation $implementation; public bool $preserveWhiteSpace = true; public bool $recover; public bool $resolveExternals; public bool $standalone; public bool $strictErrorChecking = true; public bool $substituteEntities; public bool $validateOnParse = false; public string $version; readonly public string $xmlEncoding; public bool $xmlStandalone; public string $xmlVersion; /* Métodos */ public __construct(string $version = ?, string $encoding = ?) public createAttribute(string $name): DOMAttr public createAttributeNS(string $namespaceURI, string $qualifiedName): DOMAttr public createCDATASection(string $data): DOMCDATASection public createComment(string $data): DOMComment public createDocumentFragment(): DOMDocumentFragment public createElement(string $name, string $value = ?): DOMElement public createElementNS(string $namespaceURI, string $qualifiedName, string $value = ?): DOMElement public createEntityReference(string $name): DOMEntityReference public createProcessingInstruction(string $target, string $data = ?): DOMProcessingInstruction public createTextNode(string $content): DOMText public getElementById(string $elementId): DOMElement public getElementsByTagName(string $name): DOMNodeList public getElementsByTagNameNS(string $namespaceURI, string $localName): DOMNodeList public importNode(DOMNode $importedNode, bool $deep = false): DOMNode public load(string $filename, int $options = 0): mixed public loadHTML(string $source, int $options = 0): bool public loadHTMLFile(string $filename, int $options = 0): bool public loadXML(string $source, int $options = 0): mixed public normalizeDocument(): void public registerNodeClass(string $baseclass, string $extendedclass): bool public relaxNGValidate(string $filename): bool public relaxNGValidateSource(string $source): bool public save(string $filename, int $options = 0): int public saveHTML(DOMNode $node = NULL): string public saveHTMLFile(string $filename): int public saveXML(DOMNode $node = ?, int $options = 0): string public schemaValidate(string $filename, int $flags = 0): bool public schemaValidateSource(string $source, int $flags = ?): bool public validate(): bool public xinclude(int $options = 0): int /* Métodos heredados */ public DOMNode::appendChild(DOMNode $newnode): DOMNode public DOMNode::C14N( bool $exclusive = ?, bool $with_comments = ?, array $xpath = ?, array $ns_prefixes = ? ): string public DOMNode::C14NFile( string $uri, bool $exclusive = false, bool $with_comments = false, array $xpath = ?, array $ns_prefixes = ? ): int public DOMNode::cloneNode(bool $deep = ?): DOMNode public DOMNode::getLineNo(): int public DOMNode::getNodePath(): string public DOMNode::hasAttributes(): bool public DOMNode::hasChildNodes(): bool public DOMNode::insertBefore(DOMNode $newnode, DOMNode $refnode = ?): DOMNode public DOMNode::isDefaultNamespace(string $namespaceURI): bool public DOMNode::isSameNode(DOMNode $node): bool public DOMNode::isSupported(string $feature, string $version): bool public DOMNode::lookupNamespaceUri(string $prefix): string public DOMNode::lookupPrefix(string $namespaceURI): string public DOMNode::normalize(): void public DOMNode::removeChild(DOMNode $oldnode): DOMNode public DOMNode::replaceChild(DOMNode $newnode, DOMNode $oldnode): DOMNode }
Métodos
A continuación una tabla de los métodos de la clase DomDocument
Metodos | Atributos | retorno |
__construct | $version, $encoding | void |
createAttribute | $name | DOMAttr(obj) |
createAttributeNS | $namespaceURI, $qualifiedName | DOMAttr(obj) |
createCDATASection | $data | DOMCDATASection |
createComment | $data | DOMComment |
createDocumentFragment | DOMDocumentFragment | |
createElement | $name,$value | DOMElement |
createElementNS | $namespaceURI,$qualifiedName,$value | DOMElement |
createEntityReference | $name | DOMEntityReference |
createProcessingInstruction | $target,$data | DOMProcessingInstruction |
createTextNode | $content | DOMText |
getElementById | $elementId | DOMElement |
getElementsByTagName | $name | DOMNodeList |
getElementByTagNameNS | $namespaceURI,$localName | DOMNodeList |
importNode | $importedNode, $deep | DOMNode |
load | $filename,$options | mixed |
loadHTML | $source, $options | bool |
loadHTMLFile | $filename, $options | bool |
loadXML | $source,$options | mixed |
normalizeDocument | void | |
registerNodeClass | $baseclass, $extendedclass | bool |
relaxNGValidate | $filename | bool |
relaxNGValidateSource | $source | bool |
save | $filename,$options | int |
saveHTML | $node | string |
saveHTMLFile | $filename | int |
saveXML | $node, $option | string |
schemaValidate | $filename,$flag | bool |
schemaValidateSource | $source,$flag | bool |
validate | bool | |
xinclude | $options | int |
Recordemos que estaremos trabajando con XML, y por tanto los métodos que hablan sobre namespace están referendo a los namespace en XML no en PHP.
Puedes entrar en el siguiente link de Namespaces en XML para mas info sobre el tema.
createAttribute
Crea un atributo. Para ver como utilizar este método crearemos un objeto DOMDocument $objDom
<?php $objDom = new DOMDocument(); $main = $objDom->createElement("main"); $text = $objDom->createElement("p","this is an example of blastcoding.com, domatributte"); $attribute = $objDom->createAttribute("id"); $attribute->value ="main"; $objDom->appendChild($main); $main->appendChild($attribute); $main->appendChild($text); //thanks to prefer us, Blastcoding.com echo $objDom->saveHTML();
Este ejemplo puede parecerte que tiene mucho código pero no en realidad tuve que crear un elemento al cual aplicarle el atributo ademas hay algo que tengo que recalcar aquí.
para poder mostrar el html debes ligar el elemento a el objeto Dom.
$objDom->appendChild($main);
Ademas de esto esta linea puedes tenerla después de crear el elemento, de ahí puede estar donde quieras.
Si quieres comparar el DOMDocument con algo de la vida real puedes compararlo con un juego de legos cuando creo el objeto dom tengo la caja de legos y con ellos los conecto como desee hacerlo.
createAttributeNS
Crea un nuevo nodo atributo con un namespace asociado. en pocas palabras crea un atributo con xmlns o xmlns:name
su sintaxis seria:
public DOMDocument::createAttributeNS(string $namespaceURI, string $qualifiedName): DOMAttr
que sea un atributo el retorno es entendible, veamos mas en concreto lo que podremos hacer con este método.
Tengamos en cuenta este ejemplo:
<book xmlns:bookinfo="urn:isbn:9780553382563"> <title>I Robot</title> <author>Isac Asimov</author> </book>
¿Como puedo crear esto a partir de PHP?
Primero hagamos que imprima el xml sin nuestro namespace. El siguiente codigo deberia ser suficiente:
<?php $objDom2 = new DOMDocument(); $book = $objDom2->createElement("book"); $title = $objDom2->createElement("title","I Robot"); $author = $objDom2->createElement("author","Isac Asimov"); $objDom2->appendChild($book); $book->appendChild($title); $book->appendChild($author); header('Content-type: text/xml'); echo $objDom2->saveXML(); ?>
<book> <title>I Robot</title> <author>Isac Asimov</author> </book>
vamos a agregar nuestro namespace
<?php $objDom2 = new DOMDocument("1.0"); $book = $objDom2->createElement("book"); $title = $objDom2->createElement("title","I Robot"); $author = $objDom2->createElement("author","Isac Asimov"); $objDom2->appendChild($book); $nsatributte = $objDom2->createAttributeNS("http://blastcoding.com","web"); $book->appendChild($nsatributte); $book->appendChild($title); $book->appendChild($author); header('Content-type: text/xml'); echo $objDom2->saveXML(); ?>
<book xmlns="http://blastcoding.com" web=""> <title>I Robot</title> <author>Isac Asimov</author> </book>
Vea que hemos puesto por encima el appendChild de $book de nuestro atributo, esto es porque necesitas un elemento que sea raíz.
Recomendado
En caso de que estés muy interesado en XML dejo este libro por si lo deseas comprar en Amazon, el cual posee mucha mas información de la que pueda brindar el blog. Los temas dados en el blog son temas concretos y que tienen que ver con PHP.createCDATASection
Crea un nodo que es una sección CDATA(XML), en caso de no tener idea de lo que es ver seccion-cdata-en-xml.
Sintaxispublic DOMDocument::createCDATASection(string $data): DOMCdataSection|false
Este método devuelve un objeto DOMCdataSection en caso de haber un error devolverá false.
Veamos un ejemplo:
<?php $objDom = new DOMDocument(); $main = $objDom->createElement("main"); $cdata = $objDom->createCDATASection("<code>//here goes the code</code>"); $objDom->appendChild($main); $main->appendChild($cdata); header('Content-type: text/xml'); echo $objDom->saveXML();
createComment
El método createComment crea un nodo comentario DOMComment(HTML o XML commnet).
public DOMDocument::createComment(string $data): DOMComment
Estilo de comentario
hagamos un ejemplo:
<?php $objDom = new DOMDocument(); $main = $objDom->createElement("main"); $comment = $objDom->createComment("this is a comment"); $objDom->appendChild($main); $main->appendChild($comment); header('Content-type: text/xml'); echo $objDom->saveXML();
createDocumentFragment
La primera vez que vi createDocumentFragment me pregunte que hace acaso cada nodo no hace lo mismo que esta funcion, pues no resulta que la función createDocumentFragment crea un objeto DOMDocumentFragment el cual hereda de DOMNode pero a su vez agrega un metodo el cual es appendXML().
Este método puede sernos realmente util, imagina estar utilizando una api de un tercero que te devuelve un XML y nuestro programa solo tiene que agregar algo y volver a mandar como un XML su contenido.
Sintaxispublic DOMDocument::createDocumentFragment(): DOMDocumentFragment
en caso de fallar devolvera false
¿Como podriamos simular una pagina que nos devuelve un XML con lo dado hasta ahora?
Lo único que se me ocurre es utilizar file_get_contents y así simular la devolución que hace una API claro que lo que haremos sera un XML para simular esto. Utilizemos el ejemplo del CDATA.
an XML file(cdata.xml)<?xml version="1.0"?> <datainside> <greeting>Hello, world!</greeting> <data> <![CDATA[ <greeting>Hello, world!</greeting> ]]> </data> </datainside>
veamos un ejemplo simple de como crearlo:
<?php function cleanXML($file){ $xmlpos = strpos($file,"?>"); return substr($file, $xmlpos+2,strlen($file)); } $objDom = new DOMDocument("1.0"); $fragment =$objDom->createDocumentFragment(); $XMLfile = file_get_contents("cdata.xml"); $fragment->appendXML(cleanXML($XMLfile)); $objDom->appendChild($fragment); header('Content-type: text/xml'); echo $objDom->saveXML();
Lo que hace la función es claro y no creo que necesite explicación, aunque de todos modos explicaremos lo que hace y es limpiar el la definición de la presentación de XML.
createElement
Crea un elemento, sus parametros son $name y $value siendo value un parámetro opcional.
Sintaxispublic DOMDocument::createElement(string $name, string $value = ?): DOMElement
Creo que no necesitaríamos mas ejemplos sobre este método ya que lo venimos usando desde el inicio de la pagina, de todos modos daremos el ejemplo mas simple que se pueda hacer con este método.
<?php $objDom = new DOMDocument(); $main = $objDom->createElement("main"); $text = $objDom->createElement("p","this is an example of blastcoding.com createElement"); $objDom->appendChild($main); $main->appendChild($text); echo $objDom->saveHTML();
createElementNS
crea un elemento vinculado a un namespace, ya hablamos de xmlns antes en createAtributteNS tambien puedes chequear la pagina de namespaces en XML para tener mas claro de lo que se esta hablando.
Sintaxispublic DOMDocument::createElementNS(?string $namespace, string $qualifiedName, string $value = ""): DOMElement|false
vamos rápidamente a crear un elemento de este estilo:
<?php $objDom = new DOMDocument(); $main = $objDom->createElementNS("blastcoding.com/info","info:main","root element");//tenga en cuenta que blastcoding.com/info no existe solo lo estoy usando como parte logica $text = $objDom->createElementNS("blastcoding.com/info","info:p","this is an example of blastcoding.com createElementNS"); $objDom->appendChild($main); $main->appendChild($text); header('Content-type: text/xml'); echo $objDom->saveXML();
<info:main xmlns:info="blastcoding.com/info"> root element <info:p>this is an example of blastcoding.com createElement </info:p> </info:main>
Lo que acabo de hacer anteriormente es un scoped namespace.
createEntityReference
Crea una entity Reference como un nodo. ¿Que es la entidad a la que se refiere? son grupos de letras los cuales representaran un symbolo especial. Estos son los simbolos que deberia poder reperesentar https://dev.w3.org/html5/html-author/charref.
Sintaxispublic DOMDocument::createEntityReference(string $name): DOMEntityReference
La variable $name debe ser escrita sin el simbolo & inicial y sin el simbolo ; final.
<?php $dom=new DOMDocument("1.0","UTF-8"); $example=$dom->createElement("example","who are you"); $entity=$dom->createEntityReference("quest"); $example->appendChild($entity); $dom->appendChild($example); echo $dom->saveXML();
who are you?
Recuerde que lo que pide createEntityReference es un entity name un valor numerico tanto decimal como hexa no funcionara
createProcessingInstruction
Las instrucciones de proceso o procesing instructions en ingles(PI) nos permite tener en el documento instrucciones para aplicaciones.
Con createPrcesingInstruction crearemos un nodo de PI
Las instrucciones de proceso en si no son muy utilizadas ecepto cuando se agrega estilo a nuestro XML, igual tenga en cuenta que hay otras formas de agregar estilo a nuestro XML. Una de estas formas es explicada por Bert Bos en https://www.w3.org/Style/styling-XML.en.html
Estilo CSS en XML<?xml-stylesheet href="style.css" type="text/css"?>
Tambien puedes usar estilos XLS
<?xml-stylesheet type="text/xsl" href="myxls.xsl"?>
¿Pero me estas hablando de XML como lo hago atravez de PHP?
Si antes de utilizar una funcion tenmos que saber que accion realiza. No tiene sentido decir esto se hace asi y ya.
Ahora si vamos a PHP
Sintaxispublic DOMDocument::createProcessingInstruction(string $target, string $data = ""): DOMProcessingInstruction|false
$data sera el contenido de la instruccion y $target sera el objetivo de la instruccion
Hagamos un ejemplo pero primero necesitaremos un archivo style.css:
book{ display: block; padding: 5px; background-color:aquamarine; } title,author{ display: block; max-width:300px; padding: 5px; background-color:rebeccapurple; border:1px solid white; color:white; }
Ahora tenemos que hacer nuestro archivo php.
$objDom2 = new DOMDocument(); $css = $objDom2->createProcessingInstruction('xml-stylesheet', 'type="text/css" href="style.css"'); $book = $objDom2->createElement("book"); $title = $objDom2->createElement("title","I Robot"); $author = $objDom2->createElement("author","Isac Asimov"); $objDom2->appendChild($css); $objDom2->appendChild($book); $book->appendChild($title); $book->appendChild($author); header('Content-type: text/xml'); echo $objDom2->saveXML(); ?>
createTextNode
Crea un Nodo de texto
Sintaxispublic DOMDocument::createTextNode(string $content): DOMText
Ejemplo:
<?php $objDom = new DOMDocument(); $main = $objDom->createElement("main"); $text = $objDom->createElement("p","this is an example of blastcoding.com createElement"); $extraText = $objDom->createTextNode("extra content here"); $objDom->appendChild($main); $main->appendChild($text); $main->appendChild($extraText); header('Content-type: text/xml'); echo $objDom->saveXML();
<main> <p>this is an example of blastcoding.com createElement</p> extra content here </main>[ADS_A1/]
getElementById
Este metodo es similar a getElementById de javascript, de echo realiza la misma accion, obtiene un elemento perteneciente a el objeto DOMDocument en el que lo estamos llamando.
Sintaxispublic DOMDocument::getElementById(string $elementId): ?DOMElement
En la sintaxis puede ver que nos puede devolver un Objeto DOMElement o null.
Ahora hagamos un ejemplo de como usar getElementById:
<?php $objDom = new DOMDocument('1.0', 'UTF-8'); $HTML = <<<HTML <!DOCTYPE html> <html> <head> <title>example of get element</title> </head> <body> <main id="xmain"> <h1>My First Heading</h1> <p>My first paragraph.</p> </main> <footer> Made by Blastcoding.com </footer> </body> </html> HTML; libxml_use_internal_errors(true); $objDom->loadHTML($HTML); $idMainElement = $objDom->getElementById('xmain'); if($idMainElement != null){ echo $idMainElement->nodeValue; }else{ echo "couldn't get element"; }
getElementsByTagName
El método getElementsByTagName también tiene su similar en JavaScript, este obtiene el elemento por su nombre de etiqueta(tag).
Note que este método obtendrá todos los elemento con esa etiqueta, vea el siguiente ejemplo:
<?php $objDom = new DOMDocument('1.0', 'UTF-8'); $HTML = <<<HTML <!DOCTYPE html> <html> <head> <title>example of get element</title> </head> <body> <main id="xmain"> <h1>My First Heading</h1> <p>My first paragraph.</p> </main> <footer> Made by Blastcoding.com </footer> </body> </html> HTML; libxml_use_internal_errors(true); $objDom->loadHTML($HTML); $elements = $objDom->getElementsByTagName('main'); if($elements != null){ echo $elements[0]->nodeValue; }else{ echo "couldn't get elements"; }
getElementByTagNameNS
Comming Soon
Under research, or under creation
importNode
Importa un nodo hacia el documento actual.
public DOMDocument::importNode(DOMNode $importedNode, bool $deep = false): DOMNode
En este ejemplo tomamos lo antes dado en getElementById y lo modificamos para importar un elemento de un DOMDocument a otro.
<?php $objDom = new DOMDocument('1.0', 'UTF-8'); $otherDom = new DOMDocument(); $HTML = <<<HTML <!DOCTYPE html> <html> <head> <title>example of get element</title> </head> <body> <main id="xmain"> <h1>My First Heading</h1> <p>My first paragraph.</p> </main> <footer> Made by Blastcoding.com </footer> </body> </html> HTML; libxml_use_internal_errors(true); $objDom->loadHTML($HTML); $idMainElement = $objDom->getElementById('xmain'); if($idMainElement != null){ $node = $otherDom->importNode($idMainElement, true); $otherDom->appendChild($node); header('Content-type: text/xml'); echo $otherDom->saveXML(); }else{ echo "couldn't get element"; }
load
Comming Soon
Under research, or under creation
loadHTML
Comming Soon
Under research, or under creation
loadHTMLFile
Comming Soon
Under research, or under creation
loadXML
Comming Soon
Under research, or under creation
normalizeDocument
Comming Soon
Under research, or under creation
registerNodeClass
Comming Soon
Under research, or under creation
relaxNGValidate
Comming Soon
Under research, or under creation
relaxNGValidateSource
Comming Soon
Under research, or under creation
save
Comming Soon
Under research, or under creation
saveHTML
Comming Soon
Under research, or under creation
saveHTMLFile
Comming Soon
Under research, or under creation
saveXML
Comming Soon
Under research, or under creation
schemaValidate
Comming Soon
Under research, or under creation
schemaValidateSource
Comming Soon
Under research, or under creation
validate
Comming Soon
Under research, or under creation
xinclude
Comming Soon
Under research, or under creation