Специфични за локализация съобщения в Xerces 2.11.0 (Java)

Искам да използвам специфични за локала съобщения за грешка с моите JAXP и Xerces2. По подразбиране са налични само съобщения на английски.

Първата стъпка е да извлечете файловете със съобщения и да ги поставите в пакета "org/apache/xerces/impl/msg/" - готово. С помощта на Locale.setDefault (Locale.GERMANY) се показват немските съобщения, така че това работи.

Но искам съобщенията да бъдат локализирани по различен начин за всеки екземпляр. Така че един анализатор трябва да връща съобщения на английски, а друг анализатор трябва да връща съобщения на немски.

Кодът, който използвам за създаване на анализатори на SAX2, е:

org.xml.sax.XMLReader ret = XMLReaderFactory.createXMLReader ();

за DOM използвам DocumentBuilder харесва това (много опростено):

    final DocumentBuilderFactory aDocumentBuilderFactory = DocumentBuilderFactory.newInstance ();
    final DocumentBuilder aDocBuilder = aDocBuilderFactory.newDocumentBuilder ();
    final Document doc = aDocumentBuilder.parse (aInputSource);

Намерих нещо като класа org.apache.xerces.impl.XMLErrorReporter, който има метод setLocale(Locale), но не намерих начин да го получа/настроя.

Между другото, преминаването към SAX1 не е опция.

Всяка помощ се оценява!


person Philip Helger    schedule 30.08.2013    source източник


Отговори (3)


Не е максималната преносимост, но работи, тъй като анализаторът е анализаторът на apache в 99% от всички случаи.

final DocumentBuilderFactory aDocBuilderFactory = DocumentBuilderFactory.newInstance();
aDocBuilderFactory.setAttribute("http://apache.org/xml/properties/locale", Locale.FRANCE);
final DocumentBuilder aDocBuilder = aDocBuilderFactory.newDocumentBuilder();
final Document doc = aDocBuilder.parse (aInputSource);

За SAXParser saxParser просто се обадете на saxParser.setProperty("http://apache.org/xml/properties/locale", Locale.FRANCE);

О, забравих официалния източник: http://xerces.apache.org/xerces2-j/properties.html

person Holger    schedule 11.09.2013
comment
Благодаря - точно това търсех! - person Philip Helger; 12.09.2013
comment
Забележка: ако искате да принудите съобщения за проверка на английски, може да се наложи да въведете празен обект Locale. Това е така, защото JRE не включва XMLMessage_en.properties и по този начин опитва набора от локали по подразбиране (в моя случай немски или френски), който разрешава добре включените пакети. С използването на празен Locale вие принуждавате механизма ResourceBundle просто да опита основното име (което в JRE съдържа английските свойства). - person beat; 20.02.2017
comment
Малка забележка, защото се натъкнах на подобен проблем при използване на XSD валидиране: Ако имате Validator екземпляр, можете да използвате validator.setProperty("http://apache.org/xml/properties/locale", Locale.FRANCE); - но внимавайте, ако имате Locale с en език, но не-английски локал по подразбиране - използвайте Locale.ROOT, за да наложите английски съобщения! - person Philip Helger; 26.01.2018
comment
@PhilipHelger Благодаря за бележката, много е полезна. За да наложим използването на английски за потребители, които не са английски, трябва да използваме Locale.ROOT. - person h2o2; 15.04.2021

Възможност за задаване/получаване на MessageFormatter:

Validator validator = schema.newValidator();      
XMLErrorReporter property = (XMLErrorReporter) validator.getProperty("http://apache.org/xml/properties/internal/error-reporter");
MessageFormatter messageFormatter = property.getMessageFormatter("http://www.w3.org/TR/xml-schema-1");
property.putMessageFormatter(MyMessageFormatter.SCHEMA_DOMAIN, new MyMessageFormatter());


public class MyMessageFormatter implements MessageFormatter {
    public static final String SCHEMA_DOMAIN = "http://www.w3.org/TR/xml-schema-1";
    //...
    public String formatMessage(Locale locale, String key, Object[] arguments)
            throws MissingResourceException {...}
    //...

}
person upx1988    schedule 09.04.2015

Мисля, че трябва да опитате да използвате

com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter 

Ако пишете персонализирано валидиране, опитайте да извикате неговия метод formatMessage(...), където можете да предоставите името на локала като параметър.

Пример за същото е предоставен в самата библиотека на apache. Вижте го http://cr.openjdk.java.net/~coffeys/openJDK.7u21.sync/webrev/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessageFormatter_zh_CN.java-.html

or

http://www.docjar.com/html/api/com/sun/org/apache/xerces/internal/impl/msg/XMLMessageFormatter.java.html

Друг подход може да бъде, че можете да замените метода formatMessage(), за да го приложите по ваш собствен начин. Вижте внедрения по-долу код на този метод:

 public String More ...formatMessage(Locale locale, String key, Object[] arguments)
         throws MissingResourceException {
          if (fResourceBundle == null || locale != fLocale) {
             if (locale != null) {
                 fResourceBundle = PropertyResourceBundle.getBundle("com.sun.org.apache.xerces.internal.impl.msg.XMLMessages", locale);
                 // memorize the most-recent locale
                 fLocale = locale;
             }
             if (fResourceBundle == null)
                 fResourceBundle = PropertyResourceBundle.getBundle("com.sun.org.apache.xerces.internal.impl.msg.XMLMessages");
         }

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

person Gyanendra Dwivedi    schedule 08.09.2013
comment
Мислех да използвам XMLMessageFormatter, но в предоставения пример те използват някои XMLSchemaValidatorComponentManager, за да получат и актуализират XMLMessageFormatter (който аз нямам). Трябва да има начин да го направите със стандартната настройка на DocumentBuilder.... - person Philip Helger; 08.09.2013
comment
Съжалявам, грешката ми е.. Бях поставил грешна връзка.. Актуализирах правилната. Надявам се това да помогне. - person Gyanendra Dwivedi; 08.09.2013
comment
Благодаря за актуализирането на връзката. Така че ми се струва, че не мога да задам локал директно. И така, как мога да настроя XMLMessageFormatter? Кое свойство да използвам? Въпреки че това решение не е оптимално, защото е обвързващо с Xerces..... - person Philip Helger; 09.09.2013
comment
Предполагам, че трябва да използвате метода formatMessage() тук. Едно нещо, което мога да предложа, че ако желаете да имате метод за настройка, трябва да помислите за създаване на дъщерен клас с метод за настройка за локал и ваш собствен метод за форматиране, който ще извика super.formatMessage() на родителя, предавайки информацията за локала, зададена чрез настройка метод. - person Gyanendra Dwivedi; 10.09.2013
comment
Но това напълно пречи на фабричната концепция на JAXP - трябва да има лесен начин просто да зададете локал (или средство за форматиране на съобщения) на DocumentBuilder или DocumentBuilderFactory - person Philip Helger; 10.09.2013
comment
Параметърът formatMessage() има опция за изпращане на Locale. Просто така искате да го преминете. Ако искате да получите локала от системата (като java.util.ResourceBundle.getLocale()) и да го изпратите като параметър на formatMessage(), трябва да сте готови. - person Gyanendra Dwivedi; 10.09.2013
comment
Добре, и как да настроя XMLMessageFormatter? - person Philip Helger; 10.09.2013