studio recorrer programacion obtener nodos elemento ejemplo xml simplexml php libxml2

recorrer - Cómo comprobar si una cadena es un XML válido sin mostrar una advertencia en PHP



obtener id de un elemento javascript (6)

Estaba tratando de verificar la validez de una cadena como xml usando esta función de simplexml_load_string()Docs pero muestra una gran cantidad de mensajes de advertencia.

¿Cómo puedo verificar si una cadena es un XML válido sin suprimir ( @ al principio ) el error y mostrar una función de advertencia que expec?


Use libxml_use_internal_errors () para suprimir todos los errores XML, y libxml_get_errors () para iterar sobre ellos después.

Simple cadena de carga XML

libxml_use_internal_errors(true); $doc = simplexml_load_string($xmlstr); $xml = explode("/n", $xmlstr); if (!$doc) { $errors = libxml_get_errors(); foreach ($errors as $error) { echo display_xml_error($error, $xml); } libxml_clear_errors(); }


Caso

En ocasiones, verifique la disponibilidad de un feed XML de Google Merchant.

El feed no tiene DTD, por lo que validate() no funcionará.

Solución

// disable forwarding those load() errors to PHP libxml_use_internal_errors(true); // initiate the DOMDocument and attempt to load the XML file $dom = new /DOMDocument; $dom->load($path_to_xml_file); // check if the file contents are what we''re expecting them to be // `item` here is for Google Merchant, replace with what you expect $success = $dom->getElementsByTagName(''item'')->length > 0; // alternatively, just check if the file was loaded successfully $success = null !== $dom->actualEncoding;

length anterior contiene una cantidad de la cantidad de productos que realmente figuran en el archivo. Puede utilizar sus nombres de etiqueta en su lugar.

Lógica

Puede llamar a getElementsByTagName() en cualquier otro nombre de etiqueta (el item que utilicé es para Google Merchant, su caso puede variar) o leer otras propiedades en el objeto $dom sí. La lógica sigue siendo la misma: en lugar de comprobar si hubo errores al cargar el archivo, creo que intentar manipularlo (o verificar específicamente si contiene los valores que realmente necesita) sería más confiable.

Lo más importante: a diferencia de validate() , esto no requerirá que su XML tenga una DTD.


Aquí un pequeño fragmento de clase que escribí hace un tiempo:

/** * Class XmlParser * @author Francesco Casula <[email protected]> */ class XmlParser { /** * @param string $xmlFilename Path to the XML file * @param string $version 1.0 * @param string $encoding utf-8 * @return bool */ public function isXMLFileValid($xmlFilename, $version = ''1.0'', $encoding = ''utf-8'') { $xmlContent = file_get_contents($xmlFilename); return $this->isXMLContentValid($xmlContent, $version, $encoding); } /** * @param string $xmlContent A well-formed XML string * @param string $version 1.0 * @param string $encoding utf-8 * @return bool */ public function isXMLContentValid($xmlContent, $version = ''1.0'', $encoding = ''utf-8'') { if (trim($xmlContent) == '''') { return false; } libxml_use_internal_errors(true); $doc = new DOMDocument($version, $encoding); $doc->loadXML($xmlContent); $errors = libxml_get_errors(); libxml_clear_errors(); return empty($errors); } }

Funciona bien con streams y vfsStream también para propósitos de prueba.


De la documentation :

Tratar con errores XML al cargar documentos es una tarea muy simple. Usando la funcionalidad libxml es posible suprimir todos los errores XML al cargar el documento y luego iterar sobre los errores.

El objeto libXMLError , devuelto por libxml_get_errors() , contiene varias propiedades que incluyen el message , la line y la column (posición) del error.

libxml_use_internal_errors(true); $sxe = simplexml_load_string("<?xml version=''1.0''><broken><xml></broken>"); if (!$sxe) { echo "Failed loading XML/n"; foreach(libxml_get_errors() as $error) { echo "/t", $error->message; } }

Referencia: libxml_use_internal_errors


Mi versión como esta:

//validate only XML. HTML will be ignored. function isValidXml($content) { $content = trim($content); if (empty($content)) { return false; } //html go to hell! if (stripos($content, ''<!DOCTYPE html>'') !== false) { return false; } libxml_use_internal_errors(true); simplexml_load_string($content); $errors = libxml_get_errors(); libxml_clear_errors(); return empty($errors); }

Pruebas:

//false var_dump(isValidXml(''<!DOCTYPE html><html><body></body></html>'')); //true var_dump(isValidXml(''<?xml version="1.0" standalone="yes"?><root></root>'')); //false var_dump(isValidXml(null)); //false var_dump(isValidXml(1)); //false var_dump(isValidXml(false)); //false var_dump(isValidXml(''asdasds''));


prueba este

//check if xml is valid document public function _isValidXML($xml) { $doc = @simplexml_load_string($xml); if ($doc) { return true; //this is valid } else { return false; //this is not valid } }