web-dev-qa-db-fra.com

Un caractère XML non valide (Unicode: 0xc) a été trouvé

Analyser un fichier XML à l'aide de l'analyseur DOM Java DOM donne:

[Fatal Error] os__flag_8c.xml:103:135: An invalid XML character (Unicode: 0xc) was found in the element content of the document.
org.xml.sax.SAXParseException: An invalid XML character (Unicode: 0xc) was found in the element content of the document.
    at com.Sun.org.Apache.xerces.internal.parsers.DOMParser.parse(Unknown Source)
    at com.Sun.org.Apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source)
    at javax.xml.parsers.DocumentBuilder.parse(Unknown Source)
33
Ashish

Il y a quelques caractères qui ne sont pas autorisés dans les documents XML, même lorsque vous encapsulez des données dans des blocs CDATA.

Si vous avez généré le document, vous devrez entité le coder ou dépouiller. Si vous avez un document contenant des erreurs, vous devez supprimer ces caractères avant d'essayer de l'analyser.

Voir la réponse de dolmens dans ce fil: caractères non valides en XML

Où il renvoie à cet article: http://www.w3.org/TR/xml/#charsets

Fondamentalement, tous les caractères inférieurs à 0x20 sont interdits, sauf 0x9 (TAB), 0xA (CR?), 0xD (LF?)

40
jishi
public String stripNonValidXMLCharacters(String in) {
    StringBuffer out = new StringBuffer(); // Used to hold the output.
    char current; // Used to reference the current character.

    if (in == null || ("".equals(in))) return ""; // vacancy test.
    for (int i = 0; i < in.length(); i++) {
        current = in.charAt(i); // NOTE: No IndexOutOfBoundsException caught here; it should not happen.
        if ((current == 0x9) ||
            (current == 0xA) ||
            (current == 0xD) ||
            ((current >= 0x20) && (current <= 0xD7FF)) ||
            ((current >= 0xE000) && (current <= 0xFFFD)) ||
            ((current >= 0x10000) && (current <= 0x10FFFF)))
            out.append(current);
    }
    return out.toString();
}    
8
Dima

Le caractère 0x0C n'est pas valide dans XML 1.0 mais serait un caractère valide dans XML 1.1 . Donc, sauf si le fichier xml spécifie la version 1.1 dans le prologue, il est tout simplement invalide et vous devez vous plaindre auprès du producteur de ce fichier.

6
Jörn Horstmann
2
Vikram

Chaque fois qu'un caractère xml invalide vient xml, il donne une telle erreur. Lorsque vous l'ouvrez dans notepad ++, cela ressemble à VT, SOH, FF comme ceux-ci sont des caractères xml invalides. J'utilise xml version 1.0 et je valide les données texte avant de les entrer dans la base de données par modèle

Pattern p = Pattern.compile("[^\u0009\u000A\u000D\u0020-\uD7FF\uE000-\uFFFD\u10000-\u10FFF]+"); 
retunContent = p.matcher(retunContent).replaceAll("");

Il s'assurera qu'aucun caractère spécial invalide n'entrera en XML

2
Komal

Vous pouvez filtrer tous les caractères "non valides" avec une classe FilterReader personnalisée:

public class InvalidXmlCharacterFilter extends FilterReader {

    protected InvalidXmlCharacterFilter(Reader in) {
        super(in);
    }

    @Override
    public int read(char[] cbuf, int off, int len) throws IOException {
        int read = super.read(cbuf, off, len);
        if (read == -1) return read;

        for (int i = off; i < off + read; i++) {
            if (!XMLChar.isValid(cbuf[i])) cbuf[i] = '?';
        }
        return read;
    }
}

Et lancez-le comme ceci:

InputStream fileStream = new FileInputStream(xmlFile);
Reader reader = new BufferedReader(new InputStreamReader(fileStream, charset));
InvalidXmlCharacterFilter filter = new InvalidXmlCharacterFilter(reader);
InputSource is = new InputSource(filter);
xmlReader.parse(is);
2
Vadim Zin4uk

Toutes ces réponses semblent supposer que l'utilisateur génère le mauvais XML, plutôt que de le recevoir de gSOAP, ce qui devrait être mieux connu!

0
Jerry Miller

Pour les personnes qui lisent un tableau d'octets dans une chaîne et tentent de se convertir en objet avec JAXB, vous pouvez ajouter un codage "iso-8859-1" en créant une chaîne à partir d'un tableau d'octets comme ceci:

String JAXBallowedString = new String (entrée octet [], "iso-8859-1");

Cela remplacerait l'octet en conflit par un codage à un octet que JAXB peut gérer. Évidemment, cette solution consiste uniquement à analyser le xml.

0
BatBold

J'ai rencontré un problème similaire où XML contenait des caractères de contrôle. Après avoir examiné le code, j'ai constaté qu'une classe obsolète, StringBufferInputStream, était utilisée pour lire le contenu des chaînes.

http://docs.Oracle.com/javase/7/docs/api/Java/io/StringBufferInputStream.html

This class does not properly convert characters into bytes. As of JDK 1.1, the preferred way to create a stream from a string is via the StringReader class.

Je l'ai changé en ByteArrayInputStream et cela a bien fonctionné.

0
Mohit