Недопустимый символ XML во время Unmarshall - PullRequest
10 голосов
/ 28 апреля 2011

Я сортирую объекты в XML-файл, используя кодировку "UTF-8".Он генерирует файл успешно.Но когда я пытаюсь восстановить его обратно, возникает ошибка:

В значении атрибута "{1}" обнаружен недопустимый символ XML (Unicode: 0x {2}), и элемент"0"

Символ 0x1A или \ u001a, который допустим в UTF-8, но недопустим в XML.Marshaller в JAXB позволяет записывать этот символ в XML-файл, но Unmarshaller не может разобрать его обратно.Я попытался использовать другую кодировку (UTF-16, ASCII и т. Д.), Но все равно ошибка.

Распространенным решением является удаление / замена этого недопустимого символа перед синтаксическим анализом XML.Но если нам нужен этот символ обратно, как получить исходный символ после демаршаллинга?


При поиске этого решения я хочу заменить недопустимые символы заменяющим символом (например, точка = ".") до демаршаллинга.

Я создал этот класс:

public class InvalidXMLCharacterFilterReader extends FilterReader {

    public static final char substitute = '.'; 

    public InvalidXMLCharacterFilterReader(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 -1;

        for (int readPos = off; readPos < off + read; readPos++) {
            if(!isValid(cbuf[readPos])) {
                   cbuf[readPos] = substitute;
            }
        }

        return readPos - off + 1; 
    }

    public boolean isValid(char c) {
        if((c == 0x9)
                || (c == 0xA) 
                || (c == 0xD) 
                || ((c >= 0x20) && (c <= 0xD7FF)) 
                || ((c >= 0xE000) && (c <= 0xFFFD)) 
                || ((c >= 0x10000) && (c <= 0x10FFFF)))
        {
            return true;
        } else
            return false;
    }
 }

Тогда вот как я читаю и демарширую файл:

FileReader fileReader = new FileReader(this.getFile());
Reader reader = new InvalidXMLCharacterFilterReader(fileReader);
Object o = (Object)um.unmarshal(reader);

Почему-то читательне заменять недопустимые символы тем символом, который я хочу.Это приводит к неправильным данным XML, которые не могут быть распакованы.Что-то не так с моим классом InvalidXMLCharacterFilterReader?

Ответы [ 2 ]

3 голосов
/ 28 апреля 2011

Символ Unicode U + 001A является недопустимым в XML 1.0 :

Кодировка, используемая для его представления, в данном случае не имеет значения, она просто не допускается в содержимом XML.

XML 1.1 допускает включение некоторых ограниченных символов (включая U + 001A), но они должны присутствовать в виде числовых ссылок на символы (&#x1a;)

В Википедии есть хорошее резюме ситуации .

2 голосов
/ 28 апреля 2011

Я думаю, что основная проблема заключается в экранировании недопустимых символов во время маршаллинга .Нечто подобное было упомянуто здесь , вы можете попробовать это.

Он предлагает изменить кодировку на Unicode marshaller.setProperty("jaxb.encoding", "Unicode");

...