我必须映射XML< - > Java对象,我使用JAXB进行编组和解组。这很棒。 现在我遇到了一个问题:xml标签可以使用不同的语言
示例(只有2种语言):
英文版:
<radice>
<elementoA/>
<elementoB/>
<elementoC/>
</radice>
意大利语版本:
{{1}}
问题是:如何使用一个java对象管理更多语言,以及更多具有相同结构但不同元素名称的xml源? 有没有办法动态更改注释?
目标是拥有一个单一的对象,设置其语言,然后轻松地编组和取消编组。
接口或更多对象不是解决方案,因为每个语言所涉及的对象并不容易,但数百个通常彼此嵌套。
答案 0 :(得分:0)
以下是如何使用自定义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>
以下是完成工作的片段:
@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);
}
}