Удаление неверных символов XML в Java - PullRequest
27 голосов
/ 18 сентября 2008

У меня есть XML-файл, который выводится из базы данных. Я использую синтаксический анализатор Java SAX для синтаксического анализа XML и вывода его в другом формате. XML содержит некоторые недопустимые символы, и анализатор выдает такие ошибки, как «Неверный символ Unicode (0x5)»

Есть ли хороший способ удалить все эти символы, кроме предварительной обработки файла построчно и его замены? До сих пор я столкнулся с 3 различными недопустимыми символами (0x5, 0x6 и 0x7). Это дамп базы данных ~ 4 ГБ, и мы собираемся его обработать несколько раз, поэтому каждый раз, когда мы получим новый дамп для запуска препроцессора, придется ждать еще 30 минут, и я не первый раз сталкиваюсь с этой проблемой.

Ответы [ 6 ]

21 голосов
/ 09 марта 2012

Я использовал Xalan org.apache.xml.utils.XMLChar класс:

public static String stripInvalidXmlCharacters(String input) {
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < input.length(); i++) {
        char c = input.charAt(i);
        if (XMLChar.isValid(c)) {
            sb.append(c);
        }
    }

    return sb.toString();
}
9 голосов
/ 18 сентября 2008

Я не использовал это лично, но Atlassian создал очиститель XML командной строки, который может удовлетворить ваши потребности (это было сделано в основном для JIRA, но XML - это XML):

Скачать atlassian-xml-cleaner-0.1.jar

Откройте консоль или оболочку DOS и найдите на своем компьютере файл резервной копии XML или ZIP, который предполагается здесь как data.xml

Пробег: java -jar atlassian-xml-cleaner-0.1.jar data.xml> data-clean.xml

Это приведет к записи копии data.xml в data-clean.xml с удалением недопустимых символов.

6 голосов
/ 11 октября 2011

Я использую следующее регулярное выражение, которое, как представляется, работает для JDK6:

Pattern INVALID_XML_CHARS = Pattern.compile("[^\\u0009\\u000A\\u000D\\u0020-\\uD7FF\\uE000-\\uFFFD\uD800\uDC00-\uDBFF\uDFFF]");
...
INVALID_XML_CHARS.matcher(stringToCleanup).replaceAll("");

В JDK7 возможно использовать нотацию \x{10000}-\x{10FFFF} для последнего диапазона, который находится за пределами BMP, вместо нотации \uD800\uDC00-\uDBFF\uDFFF, которую не так просто понять.

3 голосов
/ 15 ноября 2011

У меня похожая проблема при разборе содержимого австралийских экспортных тарифов в XML-документ. Я не могу использовать предложенные здесь решения, такие как: - Используйте внешний инструмент (банку), вызываемый из командной строки. - Попросите Австралийскую таможню очистить исходный файл.

Единственный метод решения этой проблемы на данный момент - это перебирать все содержимое исходного файла, посимвольно и проверять, не принадлежит ли каждый символ диапазону от 0x00 до 0x1F включительно. Это можно сделать, но мне было интересно, есть ли лучший способ использования методов Java для типа String.

EDIT Я нашел решение, которое может быть полезно для других: используйте метод Java String # ReplaceAll для замены или удаления любых нежелательных символов в документе XML.

Пример кода (я удалил некоторые необходимые операторы, чтобы избежать беспорядка):

BufferedReader reader = null;
...
String line = reader.readLine().replaceAll("[\\x00-\\x1F]", "");

В этом примере я удаляю (т.е. заменяю пустой строкой) непечатные символы в диапазоне от 0x00 до 0x1F включительно. Вы можете изменить второй аргумент в методе #replaceAll (), чтобы заменить символы на строку, которую требует ваше приложение.

0 голосов
/ 18 сентября 2008

Ваша проблема не касается XML: это касается кодировки символов. То, что сводится к тому, что каждая строка, будь то XML или иным образом, состоит из байтов, и вы не можете знать, какие символы представляют эти байты, если вам не сообщили, какой символ содержит кодировку строки. Если, например, поставщик сообщает вам, что это UTF-8, а на самом деле это что-то другое, вы обязательно столкнетесь с проблемами. В лучшем случае все работает, но некоторые байты переводятся в «неправильные» символы. В худшем случае вы получите ошибки, подобные той, с которой столкнулись.

На самом деле ваша проблема еще хуже: ваша строка содержит последовательности байтов, которые не представляют символы ни в какой кодировке символов. Здесь нет инструмента для обработки текста, не говоря уже о парсере XML. Это требует очистки на уровне байтов.

0 голосов
/ 18 сентября 2008

Возможно ли, что ваши недопустимые символы присутствуют только в пределах значений, а не самих тегов, т. Е. XML условно соответствует схеме, но значения не были должным образом очищены? Если да, то как насчет переопределения InputStream для создания CleansingInputStream, который заменяет ваши недопустимые символы их эквивалентами XML?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...