Ошибка разбора MessageFormat при разборе неанглийского сообщения

Мое приложение проверяет XML на основе файлов XSD. Результатом этой проверки является сообщение об ошибке. Чтобы показать это пользователям, я анализирую это сообщение об ошибке, используя java.text.MessageFormat. Проблема в том, что когда сообщение приходит на английском языке, я могу его нормально проанализировать, но когда сообщение приходит на португальском языке (Бразилия), возвращается ошибка ниже:

java.text.ParseException: MessageFormat parse error!
    at java.text.MessageFormat.parse(MessageFormat.java:1035)
    at com.local.messageformat.MessageFormatMain.splitMessage(MessageFormatMain.java:34)
    at com.local.messageformat.MessageFormatMain.start(MessageFormatMain.java:20)
    at com.local.messageformat.MessageFormatMain.main(MessageFormatMain.java:14)

Вот мой код:

public class MessageFormatMain {

public static void main(String[] args) {
    final MessageFormatMain main = new MessageFormatMain();
    main.start();
}

private void start() {
    final String errorMessageKey = "cvc-complex-type.2.4.a";
//Portuguese message (shows error)
    final String errorMessage = "cvc-complex-type.2.4.a: Conteúdo inválido encontrado a partir do elemento 'inscricaomunicipaltomador'. Um de '{razaosocialtomador, estrangeirotomador, tipologradourotomador, logradourotomador, numeroenderecotomador, bairrotomador, complementotomador, cidadetomadordescricao, estadotomadordescricao, fonetomador, ceptomador, emailtomador, tomadorpais, tomadorresptribut, codigoatividade, aliquotaatividade, tiporecolhimento, valortotalrps, valorservicosrps, valoriss, valorpis, valorcofins, valorinss, valorir, valorcsll, aliquotapis, aliquotacofins, aliquotainss, aliquotair, aliquotacsll, descricaorps, tributacaorps, localservico, itens}' é esperado.";
// English message (works fine)
//  final String errorMessage = "cvc-complex-type.2.4.a: Invalid content was found starting with element 'inscricaomunicipaltomador'. One of '{razaosocialtomador, estrangeirotomador, tipologradourotomador, logradourotomador, numeroenderecotomador, bairrotomador, complementotomador, cidadetomadordescricao, estadotomadordescricao, fonetomador, ceptomador, emailtomador, tomadorpais, tomadorresptribut, codigoatividade, aliquotaatividade, tiporecolhimento, valortotalrps, valorservicosrps, valoriss, valorpis, valorcofins, valorinss, valorir, valorcsll, aliquotapis, aliquotacofins, aliquotainss, aliquotair, aliquotacsll, descricaorps, tributacaorps, localservico, itens}' is expected.";
    Object[] ret = splitMessage(errorMessage, errorMessageKey);
    if (ret.length > 0) {
        System.out.println(ret[0]);
        System.out.println(ret[1]);
    }
}

private Object[] splitMessage(final String errorMessage, final String errorMessageKey) {
    final ResourceBundle resourceBundle = PropertyResourceBundle.getBundle("com.sun.org.apache.xerces.internal.impl.msg.XMLSchemaMessages", Locale.ROOT);
    if (errorMessageKey != null && !errorMessageKey.isEmpty() && resourceBundle.containsKey(errorMessageKey)) {
        final String errorMessagePattern = resourceBundle.getString(errorMessageKey);
        final MessageFormat messageFormat = new MessageFormat(errorMessagePattern);
        Object arguments[];
        try {
            arguments = messageFormat.parse(errorMessage);
            return arguments;
        } catch (final ParseException e) {
            e.printStackTrace();
        }
        return new Object[0];
    }
    return new Object[0];
}

}

Я пытался указать другое местоположение, чтобы получить de ResourceBundle и даже создать экземпляр MessageFormat, но ни один из них не сработал.

Заранее спасибо.

Гильерме

2 ответа

Решение

Я разобрался с решением этой проблемы. Сначала я проверяю схему XML-файла XSD с помощью библиотеки XercesImpl, которая использует следующий пакет:

org.apache.xerces.impl.msg.XMLSchemaMessages

Сначала загруженное сообщение было на английском языке, но после обновления этой библиотеки загруженное сообщение на португальском языке. Затем, когда вызывался метод splitMessage, я ссылался на пакет Java вместо пакета XercesImpl. Очевидно, что MessageFormat.parse не удалось проанализировать португальское сообщение (извлеченное из XercesImpl) с использованием сообщения на английском языке (извлеченного из пакета Java).

Чтобы решить эту проблему, я внес простое изменение в метод splitMessage. Как это:

final ResourceBundle resourceBundle = ResourceBundle.getBundle("org.apache.xerces.impl.msg.XMLSchemaMessages");

Помня, что я установил Locale как "PT/BR" в основном методе, поэтому мне не нужно устанавливать Locale для загрузки ресурса.

Самое смешное, что в JDK есть файлы сообщений с португальской схемой, которые я использую. Так что все равно должно было сработать.

Я думаю, что ressourceBundle, который вы ищете, не переведен на португальский язык.

Я попытался переписать его на французском и протестировал его на моем французском JVM:), и это работает:

final String errorMessage = "cvc-complex-type.2.4.a : Contenu non valide trouvé à partir de l'élément 'inscricaomunicipaltomador'. L'une des valeurs '{razaosocialtomador, estrangeirotomador, tipologradourotomador, logradourotomador, numeroenderecotomador, bairrotomador, complementotomador, cidadetomadordescricao, estadotomadordescricao, fonetomador, ceptomador, emailtomador, tomadorpais, tomadorresptribut, codigoatividade, aliquotaatividade, tiporecolhimento, valortotalrps, valorservicosrps, valoriss, valorpis, valorcofins, valorinss, valorir, valorcsll, aliquotapis, aliquotacofins, aliquotainss, aliquotair, aliquotacsll, descricaorps, tributacaorps, localservico, itens}' est attendue.";

Возможно, вы могли бы попытаться найти португальскую версию ressourceBundle, которая должна называться "XMLSchemaMessages_pr.properties", и добавить ее в ваш путь к классам, согласно этому посту.

Другие вопросы по тегам