解析非英文消息时 MessageFormat 解析错误
MessageFormat parse error when parsing a non English message
我的应用程序根据 XSD 个文件验证 XML。此验证的结果是一条错误消息。为了向用户展示这一点,我使用 java.text.MessageFormat 解析此错误消息。
问题是:当消息以英语出现时,我能够正常解析它,但是当消息以葡萄牙语(巴西)出现时,它 returns 出现以下错误:
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];
}
}
我试图指定一个不同的位置来获取 ResourceBundle,甚至实例化 MessageFormat,但没有一个起作用。
提前致谢。
吉列尔梅
我想您搜索的 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",并根据 this post.
将其添加到您的类路径中
我找到了解决这个问题的方法。
在第一时间,我使用 XercesImpl 库对 XML 文件进行了 XSD 模式验证,它使用以下包:
org.apache.xerces.impl.msg.XMLSchemaMessages
首先加载的消息是英文的,但是在 更新 这个库之后,加载的消息是葡萄牙语。
然后,当调用 splitMessage 方法时,我引用了 Java 包而不是 XercesImpl 包。
显然,MessageFormat.parse 无法使用英语消息(从 Java 包中提取)解析葡萄牙语消息(从 XercesImpl 中提取)。
为了解决这个问题,我对 splitMessage 方法做了一个简单的更改。像这样:
final ResourceBundle resourceBundle = ResourceBundle.getBundle("org.apache.xerces.impl.msg.XMLSchemaMessages");
请记住,我在 main 方法中将语言环境设置为 "PT/BR",这就是为什么我不必设置语言环境来加载资源的原因。
有趣的是,我正在使用的 JDK 中有葡萄牙语架构消息文件。所以,无论如何它应该有效。
我的应用程序根据 XSD 个文件验证 XML。此验证的结果是一条错误消息。为了向用户展示这一点,我使用 java.text.MessageFormat 解析此错误消息。 问题是:当消息以英语出现时,我能够正常解析它,但是当消息以葡萄牙语(巴西)出现时,它 returns 出现以下错误:
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];
}
}
我试图指定一个不同的位置来获取 ResourceBundle,甚至实例化 MessageFormat,但没有一个起作用。
提前致谢。
吉列尔梅
我想您搜索的 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",并根据 this post.
将其添加到您的类路径中我找到了解决这个问题的方法。 在第一时间,我使用 XercesImpl 库对 XML 文件进行了 XSD 模式验证,它使用以下包:
org.apache.xerces.impl.msg.XMLSchemaMessages
首先加载的消息是英文的,但是在 更新 这个库之后,加载的消息是葡萄牙语。 然后,当调用 splitMessage 方法时,我引用了 Java 包而不是 XercesImpl 包。 显然,MessageFormat.parse 无法使用英语消息(从 Java 包中提取)解析葡萄牙语消息(从 XercesImpl 中提取)。
为了解决这个问题,我对 splitMessage 方法做了一个简单的更改。像这样:
final ResourceBundle resourceBundle = ResourceBundle.getBundle("org.apache.xerces.impl.msg.XMLSchemaMessages");
请记住,我在 main 方法中将语言环境设置为 "PT/BR",这就是为什么我不必设置语言环境来加载资源的原因。
有趣的是,我正在使用的 JDK 中有葡萄牙语架构消息文件。所以,无论如何它应该有效。