type especiales español content charset caracteres acentos java xml encoding utf-8

especiales - java acentos utf-8



eliminar caracteres que no sean UTF-8 de xml con codificación declarada=utf-8-Java (6)

Tengo que manejar este escenario en Java:

Recibo una solicitud en formato XML de un cliente con codificación declarada = utf-8. Desafortunadamente, puede contener no caracteres UTF-8 y existe un requisito para eliminar estos caracteres del xml de mi lado (herencia).

Consideremos un ejemplo en el que este XML no válido contiene £ (libra).

1) Obtengo xml como java String con £ en él (no tengo acceso a la interfaz en este momento, pero probablemente obtenga xml como java String). ¿Puedo usar replaceAll (£, "") para deshacerme de este personaje? ¿Algún problema potencial?

2) Obtengo xml como una matriz de bytes: ¿cómo manejar esta operación de manera segura en ese caso?


1) Obtengo xml como java String con £ en él (no tengo acceso a la interfaz en este momento, pero probablemente obtenga xml como java String). ¿Puedo usar replaceAll (£, "") para deshacerme de este personaje?

Supongo que prefiere decir que quiere deshacerse de los caracteres que no son ASCII , porque está hablando de un lado "heredado". Puede deshacerse de cualquier cosa fuera del rango ASCII imprimible usando la siguiente expresión regular:

string = string.replaceAll("[^//x20-//x7e]", "");

2) Obtengo xml como una matriz de bytes: ¿cómo manejar esta operación de manera segura en ese caso?

Debe envolver el byte[] en ByteArrayInputStream , de modo que pueda leerlos en una secuencia de caracteres codificados en UTF-8 utilizando InputStreamReader donde especificará la codificación y luego usará un BufferedReader para leerla línea por línea.

P.ej

BufferedReader reader = null; try { reader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(bytes), "UTF-8")); for (String line; (line = reader.readLine()) != null;) { line = line.replaceAll("[^//x20-//x7e]", ""); // ... } // ...


UTF-8 es una codificación; Unicode es un conjunto de caracteres. Pero el símbolo GBP está definitivamente en el conjunto de caracteres Unicode y, por lo tanto, es ciertamente representable en UTF-8.

Si de hecho significa UTF-8, y en realidad está tratando de eliminar secuencias de bytes que no son la codificación válida de un personaje en UTF-8, entonces ...

CharsetDecoder utf8Decoder = Charset.forName("UTF-8").newDecoder(); utf8Decoder.onMalformedInput(CodingErrorAction.IGNORE); utf8Decoder.onUnmappableCharacter(CodingErrorAction.IGNORE); ByteBuffer bytes = ...; CharBuffer parsed = utf8Decoder.decode(bytes); ...


Me enfrenté al mismo problema mientras leía archivos de un directorio local y probé esto:

BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(filePath), "UTF-8")); DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder(); Document xmlDom = db.parse(new InputSource(in));

Puede que tenga que usar su flujo de entrada de red en lugar de FileInputStream.

- Kapil


"test text".replaceAll("[^//u0000-//uFFFF]", "");

Este código elimina todos los caracteres de 4 bytes utf8 de la cadena. Esto puede ser necesario para algunos propósitos al hacer Mysql innodb varchar entry


Tenga en cuenta que el primer paso debería ser que le pregunte al creador del XML (que probablemente sea un generador XML "solo imprima datos") para asegurarse de que su XML sea correcto antes de enviarlo. La prueba más simple posible si usan Windows es pedirles que lo vean en Internet Explorer y que vean el error de análisis en el primer carácter ofensivo.

Mientras lo arreglan, simplemente puede escribir un pequeño programa que cambie la parte del encabezado para declarar que la codificación es ISO-8859-1 en su lugar:

<?xml version="1.0" encoding="iso-8859-1" ?>

y deja el resto sin tocar.


Una vez que convierte la matriz de bytes a Cadena en la máquina Java, obtendrá (por defecto en la mayoría de las máquinas) cadena codificada en UTF-16. La solución adecuada para deshacerse de los caracteres que no sean UTF-8 es con el siguiente código:

String[] values = {"//xF0//x9F//x98//x95", "//xF0//x9F//x91//x8C", "/*", "look into my eyes 〠.〠", "fkdjsf ksdjfslk", "//xF0//x80//x80//x80", "aa //xF0//x9F//x98//x95 aa"}; for (int i = 0; i < values.length; i++) { System.out.println(values[i].replaceAll( "[////x00-////x7F]|" + //single-byte sequences 0xxxxxxx "[////xC0-////xDF][////x80-////xBF]|" + //double-byte sequences 110xxxxx 10xxxxxx "[////xE0-////xEF][////x80-////xBF]{2}|" + //triple-byte sequences 1110xxxx 10xxxxxx * 2 "[////xF0-////xF7][////x80-////xBF]{3}" //quadruple-byte sequence 11110xxx 10xxxxxx * 3 , "")); }

o si quiere validar si alguna cadena contiene caracteres no utf8, debería usar Pattern.matches como:

String[] values = {"//xF0//x9F//x98//x95", "//xF0//x9F//x91//x8C", "/*", "look into my eyes 〠.〠", "fkdjsf ksdjfslk", "//xF0//x80//x80//x80", "aa //xF0//x9F//x98//x95 aa"}; for (int i = 0; i < values.length; i++) { System.out.println(Pattern.matches( ".*(" + "[////x00-////x7F]|" + //single-byte sequences 0xxxxxxx "[////xC0-////xDF][////x80-////xBF]|" + //double-byte sequences 110xxxxx 10xxxxxx "[////xE0-////xEF][////x80-////xBF]{2}|" + //triple-byte sequences 1110xxxx 10xxxxxx * 2 "[////xF0-////xF7][////x80-////xBF]{3}" //quadruple-byte sequence 11110xxx 10xxxxxx * 3 + ").*" , values[i])); }

Si tiene el conjunto de bytes disponible, puede filtrarlos aún más correctamente con:

BufferedReader bufferedReader = null; try { bufferedReader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(bytes), "UTF-8")); for (String currentLine; (currentLine = bufferedReader.readLine()) != null;) { currentLine = currentLine.replaceAll( "[//x00-//x7F]|" + //single-byte sequences 0xxxxxxx "[//xC0-//xDF][//x80-//xBF]|" + //double-byte sequences 110xxxxx 10xxxxxx "[//xE0-//xEF][//x80-//xBF]{2}|" + //triple-byte sequences 1110xxxx 10xxxxxx * 2 "[//xF0-//xF7][//x80-//xBF]{3}" //quadruple-byte sequence 11110xxx 10xxxxxx * 3 , "")); }

Para hacer que una aplicación web entera sea compatible con UTF8, lea aquí:
Cómo obtener UTF-8 trabajando en Java webapps
Más sobre Byte Encodings and Strings .
Puedes verificar tu patrón aquí .
Lo mismo en PHP aquí .