una strip_tags remove quitar para funcion etiquetas eliminar ejemplo caracteres cadena php xml utf-8

strip_tags - Cómo omitir caracteres inválidos en un archivo XML usando PHP



strip_tags wordpress (7)

Estoy tratando de analizar un archivo XML usando PHP, pero recibo un mensaje de error:

error del analizador: Char 0x0 fuera del rango permitido en

Creo que es por el contenido del XML, creo que hay un símbolo especial "☆", ¿alguna idea de qué puedo hacer para solucionarlo?

Yo también tengo:

error del analizador: final prematuro de los datos en la línea del elemento de la etiqueta

¿Qué podría estar causando ese error?

Estoy usando simplexml_load_file .

Actualizar:

Intento encontrar la línea de error y pegar su contenido como un solo archivo xml y puede funcionar. así que todavía no puedo entender qué hace que el análisis de archivos xml falle. PD: es un enorme archivo xml de más de 100M, ¿cometerá un error de análisis?


¿Tienes control sobre el XML? Si es así, asegúrese de que los datos estén incluidos en los bloques <![CDATA[ .. ]]> .

Y también necesitas borrar los caracteres inválidos:

/** * Removes invalid XML * * @access public * @param string $value * @return string */ function stripInvalidXml($value) { $ret = ""; $current; if (empty($value)) { return $ret; } $length = strlen($value); for ($i=0; $i < $length; $i++) { $current = ord($value{$i}); if (($current == 0x9) || ($current == 0xA) || ($current == 0xD) || (($current >= 0x20) && ($current <= 0xD7FF)) || (($current >= 0xE000) && ($current <= 0xFFFD)) || (($current >= 0x10000) && ($current <= 0x10FFFF))) { $ret .= chr($current); } else { $ret .= " "; } } return $ret; }



Decidí probar todos UTF-8 valores de UTF-8 (0-1114111) para asegurarme de que las cosas funcionen como deberían. El uso de preg_replace() hace que se devuelva un NULL debido a errores al probar todos los valores de utf-8. Esta es la solución que he encontrado.

$utf_8_range = range(0, 1114111); $output = ords_to_utfstring($utf_8_range); $sanitized = sanitize_for_xml($output); /** * Removes invalid XML * * @access public * @param string $value * @return string */ function sanitize_for_xml($input) { // Convert input to UTF-8. $old_setting = ini_set(''mbstring.substitute_character'', ''"none"''); $input = mb_convert_encoding($input, ''UTF-8'', ''auto''); ini_set(''mbstring.substitute_character'', $old_setting); // Use fast preg_replace. If failure, use slower chr => int => chr conversion. $output = preg_replace(''/[^/x{0009}/x{000a}/x{000d}/x{0020}-/x{D7FF}/x{E000}-/x{FFFD}]+/u'', '''', $input); if (is_null($output)) { // Convert to ints. // Convert ints back into a string. $output = ords_to_utfstring(utfstring_to_ords($input), TRUE); } return $output; } /** * Given a UTF-8 string, output an array of ordinal values. * * @param string $input * UTF-8 string. * @param string $encoding * Defaults to UTF-8. * * @return array * Array of ordinal values representing the input string. */ function utfstring_to_ords($input, $encoding = ''UTF-8''){ // Turn a string of unicode characters into UCS-4BE, which is a Unicode // encoding that stores each character as a 4 byte integer. This accounts for // the "UCS-4"; the "BE" prefix indicates that the integers are stored in // big-endian order. The reason for this encoding is that each character is a // fixed size, making iterating over the string simpler. $input = mb_convert_encoding($input, "UCS-4BE", $encoding); // Visit each unicode character. $ords = array(); for ($i = 0; $i < mb_strlen($input, "UCS-4BE"); $i++) { // Now we have 4 bytes. Find their total numeric value. $s2 = mb_substr($input, $i, 1, "UCS-4BE"); $val = unpack("N", $s2); $ords[] = $val[1]; } return $ords; } /** * Given an array of ints representing Unicode chars, outputs a UTF-8 string. * * @param array $ords * Array of integers representing Unicode characters. * @param bool $scrub_XML * Set to TRUE to remove non valid XML characters. * * @return string * UTF-8 String. */ function ords_to_utfstring($ords, $scrub_XML = FALSE) { $output = ''''; foreach ($ords as $ord) { // 0: Negative numbers. // 55296 - 57343: Surrogate Range. // 65279: BOM (byte order mark). // 1114111: Out of range. if ( $ord < 0 || ($ord >= 0xD800 && $ord <= 0xDFFF) || $ord == 0xFEFF || $ord > 0x10ffff) { // Skip non valid UTF-8 values. continue; } // 9: Anything Below 9. // 11: Vertical Tab. // 12: Form Feed. // 14-31: Unprintable control codes. // 65534, 65535: Unicode noncharacters. elseif ($scrub_XML && ( $ord < 0x9 || $ord == 0xB || $ord == 0xC || ($ord > 0xD && $ord < 0x20) || $ord == 0xFFFE || $ord == 0xFFFF )) { // Skip non valid XML values. continue; } // 127: 1 Byte char. elseif ( $ord <= 0x007f) { $output .= chr($ord); continue; } // 2047: 2 Byte char. elseif ($ord <= 0x07ff) { $output .= chr(0xc0 | ($ord >> 6)); $output .= chr(0x80 | ($ord & 0x003f)); continue; } // 65535: 3 Byte char. elseif ($ord <= 0xffff) { $output .= chr(0xe0 | ($ord >> 12)); $output .= chr(0x80 | (($ord >> 6) & 0x003f)); $output .= chr(0x80 | ($ord & 0x003f)); continue; } // 1114111: 4 Byte char. elseif ($ord <= 0x10ffff) { $output .= chr(0xf0 | ($ord >> 18)); $output .= chr(0x80 | (($ord >> 12) & 0x3f)); $output .= chr(0x80 | (($ord >> 6) & 0x3f)); $output .= chr(0x80 | ($ord & 0x3f)); continue; } } return $output; }

Y para hacer esto en un simple objeto o matriz

// Recursive sanitize_for_xml. function recursive_sanitize_for_xml(&$input){ if (is_null($input) || is_bool($input) || is_numeric($input)) { return; } if (!is_array($input) && !is_object($input)) { $input = sanitize_for_xml($input); } else { foreach ($input as &$value) { recursive_sanitize_for_xml($value); } } }


Mi problema era el carácter "&" (HEX 0x24), cambié a:

function stripInvalidXml($value) { $ret = ""; $current; if (empty($value)) { return $ret; } $length = strlen($value); for ($i=0; $i < $length; $i++) { $current = ord($value{$i}); if (($current == 0x9) || ($current == 0xA) || ($current == 0xD) || (($current >= 0x28) && ($current <= 0xD7FF)) || (($current >= 0xE000) && ($current <= 0xFFFD)) || (($current >= 0x10000) && ($current <= 0x10FFFF))) { $ret .= chr($current); } else { $ret .= " "; } } return $ret; }


No es una solución php pero funciona:

Descargue Notepad ++ https://notepad-plus-plus.org/

Abra su archivo .xml en Notepad ++

En el Menú principal: Buscar -> Modo de búsqueda, configure esto en: Extendido

Entonces,

Reemplazar -> Encuentra que / x00; Reemplazar con {dejar vacío}

Entonces, Replace_All

Robar



Si tiene control sobre los datos, asegúrese de que esté codificado correctamente (es decir, está en la codificación que prometió en la etiqueta xml, por ejemplo, si tiene:

<?xml version="1.0" encoding="UTF-8"?>

entonces deberá asegurarse de que sus datos estén en UTF-8.

Si no tienes control sobre los datos, grítales a quienes los tienen.

Puede usar una herramienta como xmllint para verificar qué parte (s) de los datos no son válidos.