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.
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 porlibxml_get_errors()
, contiene varias propiedades que incluyen elmessage
, laline
y lacolumn
(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
}
}