Был найден недопустимый символ XML (Unicode: 0xc)
Анализ XML файла с использованием парсера Java DOM приводит к:
[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)
Ответы
Ответ 1
Есть несколько символов, которые не разрешены в документах XML, даже если вы инкапсулируете данные в CDATA-блоки.
Если вы сгенерировали документ, вам понадобится объект закодировать его или удалить его. Если у вас есть ошибочный документ, вы должны удалить эти символы, прежде чем пытаться его проанализировать.
См. ответ dolmens в этой теме: Недопустимые символы в XML
Где он ссылается на эту статью: http://www.w3.org/TR/xml/#charsets
В принципе, все символы ниже 0x20 запрещены, кроме 0x9 (TAB), 0xA (CR?), 0xD (LF?)
Ответ 2
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();
}
Ответ 3
Символ 0x0C недействителен в XML 1.0, но будет допустимым символом в XML 1.1. Поэтому, если файл xml не указывает версию 1.1 в прологе, он просто недействителен, и вы должны жаловаться производителю этого файла.
Ответ 4
Эта ссылка имеет код java, который отлично работает.
http://blog.mark-mclaren.info/2007/02/invalid-xml-characters-when-valid-utf8_5873.html
Ответ 5
Всякий раз, когда недопустимый xml-символ приходит xml, он дает такую ошибку. Когда вы открываете его в блокноте ++, он выглядит как VT, SOH, FF, так как это недопустимые символы xml. Я использую xml версии 1.0 и я проверяю текстовые данные перед тем, как вводить их в базу данных по шаблону
Pattern p = Pattern.compile("[^\u0009\u000A\u000D\u0020-\uD7FF\uE000-\uFFFD\u10000-\u10FFF]+");
retunContent = p.matcher(retunContent).replaceAll("");
Он будет гарантировать, что недействительный специальный char войдет в xml
Ответ 6
Вы можете отфильтровать все "недопустимые" символы с помощью настраиваемого класса FilterReader:
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;
}
}
И запустите его так:
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);
Ответ 7
Я столкнулся с аналогичной проблемой, когда XML содержал контрольные символы. Изучив код, я обнаружил, что для чтения строкового содержимого использовался устаревший класс StringBufferInputStream.
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.
Я изменил его на ByteArrayInputStream, и он работал нормально.
Ответ 8
Для людей, которые читают массив байтов в String и пытаются преобразовать объект в JAXB, вы можете добавить кодировку iso-8859-1, создав String из байтового массива следующим образом:
String JAXBallowedString = new String (байт [] input, "iso-8859-1" );
Это заменит конфликтующий байт на однобайтную кодировку, которую может обрабатывать JAXB. Очевидно, что это решение состоит только для анализа xml.
Ответ 9
Кажется, что все эти ответы предполагают, что пользователь генерирует плохой XML, а не получает его от gSOAP, который должен знать лучше!