【问题标题】:JAXB dynamic annotations with same object具有相同对象的 JAXB 动态注释
【发布时间】:2017-09-01 14:52:21
【问题描述】:

我必须映射 XMLJava 对象,并且我使用 JAXB 进行编组和解组。这很棒。 现在我有一个问题:xml标签可以是不同的语言

示例(只有 2 种语言):

英文版:

<root>
   <elementA/>
   <elementB/>
   <elementC/>
</root>

意大利语版:

<radice>
   <elementoA/>
   <elementoB/>
   <elementoC/>
</radice>

问题是:如何使用一个 java 对象管理更多的语言、更多具有相同结构但元素名称不同的 xml 源? 有没有办法动态更改注解?

目标是拥有一个对象,设置其语言,然后轻松编组和解组。

接口或更多对象不是解决方案,因为每种语言所涉及的对象并不像示例那样简单,而是数百个经常相互嵌套。

【问题讨论】:

  • 我从未见过有人想本地化 XML 元素名称。
  • 您是否探索过将 XSL 转换应用于生成的 XML 的可能方法?
  • XML 定义应该用通用语言定义。否则将您的问题分为两部分:1)转换为英文版本 2)处理数据。
  • 这同样适用于我:xml 标签本地化非常愚蠢,但这就是我输入的内容和客户期望的输出内容。这是特定信息交换的国际标准,是的,这是一个愚蠢的想法,但我无权更改它:-)
  • xsl 和/或转换不是最好的解决方案,因为一切都是实时的,我每秒管理数千个请求和响应。有人可以用一种语言发送,另一种可以用另一种语言发送...

标签: java xml jaxb annotations


【解决方案1】:

这是一个非常草稿,如何使用自定义 XMLStreamWriter 来完成。在这些示例中,需要两个 Maven 依赖项(使用 Java 7;使用 Java 8,代码可能会更简单):

    <dependency>
        <groupId>net.java.dev.stax-utils</groupId>
        <artifactId>stax-utils</artifactId>
        <version>20070216</version>
    </dependency>
    <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>19.0</version>
    </dependency>

这里是 sn-p 做的工作:

@XmlRootElement(name = ROOT)
public static class Root {
    static final String ROOT = "root";
    static final String ELEMENT_A = "elementA";

    @XmlElement(name = ELEMENT_A)
    public Element element_a;
    public static class Element {}
}

public static void main(String[] args) throws Exception {
    final Root root = new Root();
    root.element_a = new Root.Element();

    final JAXBContext jaxbContext = JAXBContext.newInstance(Root.class);
    final Marshaller marshaller = jaxbContext.createMarshaller();

    final XMLOutputFactory outputFactory = XMLOutputFactory.newFactory();
    final XMLStreamWriter writer = outputFactory.createXMLStreamWriter(System.out);
    final LocalizingXmlStreamWriter localizingWriter = new LocalizingXmlStreamWriter(writer, Locale.ENGLISH);
    marshaller.marshal(root, localizingWriter);
}

static class LocalizingXmlStreamWriter extends javanet.staxutils.IndentingXMLStreamWriter {
    final static Map<String, ImmutableMap<String, String>> localizations = Maps.toMap(
        Arrays.asList(Locale.ENGLISH.getLanguage(), Locale.ITALIAN.getLanguage()),
        new Function<String, ImmutableMap<String, String>>() {
            @Override
            public ImmutableMap<String, String> apply(String lang) {
                if (Locale.ENGLISH.getLanguage().equals(lang)) {
                    return Maps.toMap(Arrays.asList(ROOT, ELEMENT_A),
                        Functions.<String>identity());
                }
                else if (Locale.ITALIAN.getLanguage().equals(lang)) {
                    return Maps.toMap(Arrays.asList(ROOT, ELEMENT_A),
                        new Function<String, String>() {
                            @Override
                            public String apply(String tag) {
                                switch (tag) {
                                    case ROOT:
                                        return "radice";
                                    case ELEMENT_A:
                                        return "elementoA";
                                    default:
                                        return tag;
                                }
                            }
                        });
                }
                else throw new IllegalStateException();
            }
        }
    );

    private final ImmutableMap<String, String> localization;

    public LocalizingXmlStreamWriter(XMLStreamWriter writer, Locale locale) {
        super(writer);
        final String language = locale.getLanguage();
        localization = localizations.get(language);
        Preconditions.checkArgument(localization != null, 
            "not supported language %s", language);
    }

    @Override
    public void writeStartElement(String prefix, String localName, String namespaceURI) 
        throws XMLStreamException 
    {
        final String localizedTag = localization.get(localName);
        super.writeStartElement(prefix, localizedTag, namespaceURI);
    }
}

【讨论】:

    猜你喜欢
    • 2012-01-24
    • 1970-01-01
    • 2014-08-13
    • 2015-11-12
    • 2011-06-20
    • 1970-01-01
    • 2019-06-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多