解析非英语消息时,MessageFormat解析错误

时间:2016-03-22 14:34:18

标签: java xml parsing messageformat

我的应用程序根据XSD文件验证XML。此验证的结果是错误消息。为了向用户显示此信息,我使用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 个答案:

答案 0 :(得分:0)

I guess the ressourceBundle you are searching is not translated in Portuguese.

I tried to rewrite it in french and tested it on my french JVM :) and it works :

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.";

Perhaps you could try to find a portuguese version of the ressourceBundle, which should be named "XMLSchemaMessages_pr.properties", and add it to your classpath, according to this post

答案 1 :(得分:0)

我找到了解决这个问题的方法。 在第一时间,我使用XercesImpl lib对XML文件进行XSD架构验证,使用以下包:

org.apache.xerces.impl.msg.XMLSchemaMessages

首先,加载的邮件是英文的,但在此lib的更新之后,加载的邮件是葡萄牙语。 然后,当调用splitMessage方法时,我引用了Java包而不是XercesImpl包。 显然,MessageFormat.parse无法使用英文消息(从Java包中提取)解析葡萄牙语消息(从XercesImpl中提取)。

为了解决这个问题,我在splitMessage方法中做了一个简单的改动。像这样:

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

记住我在主方法中将Locale设置为“PT / BR”,这就是为什么我不必将Locale设置为加载资源。

有趣的是,我正在使用的JDK中有葡萄牙语架构消息文件。所以,无论如何它应该有用。