Подтвердить что ты не робот

Удаление запрещенных символов XML в Java

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

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

4b9b3361

Ответ 1

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

Загрузить atlassian-xml-cleaner-0.1.jar

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

Run:  java -jar atlassian-xml-cleaner-0.1.jar data.xml > data-clean.xml

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

Ответ 2

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

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();
}

Ответ 3

Я использую следующее regexp, которое, как представляется, работает для 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, которое не так просто понять.

Ответ 4

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

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

ИЗМЕНИТЬ Я нашел решение, которое может быть полезным для других: Используйте метод Java String # ReplaceAll для замены или удаления любых нежелательных символов в XML-документе.

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

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

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

Ответ 5

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

Ответ 6

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

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