我正在尝试使用 MOXy 为跨多个包的类自定义 XML 编码和架构生成的命名算法。
我正在关注 Eclipse documentation并可以让它为单个类工作:
@XmlNameTransformer(com.example.test.NameGenerator.class)
public class Customer
或单个包:
@XmlNameTransformer(com.example.test.NameGenerator.class)
package com.example.test;
(外部绑定(bind)文件也可以使用,但同样,您只能为每个绑定(bind)文件指定包)
但是,由于我的对象跨越多个包,所以我不想为每个包定义转换器。另外,我想动态地执行此操作(即,直到运行时才知道各个包)。
我尝试在父包 (com.example
) 中定义转换器,但这不起作用 - 看起来它需要是带注释的类所在的确切包。
有什么想法吗?
更新 - 更多信息
也许我应该提到我尝试这样做的主要原因,以便我可以控制 XML/XSD 生成 - 最具体地说,我希望复杂类型为大写而不是默认的小写(不需要注释每个类),例如
@XmlRootElement
public class Test ...
应该生成:
<Test>
...
</Test>
而不是
<test>
...
</test>
根据我所做的其他研究,我发现实现此目的的唯一方法是使用 XmlNameTransformer
。但如果有另一种方法,而我找错了树……一定要让我知道!
最佳答案
扩展 Blaise 的答案,这是我的实现的样子。这通过使用一组动态包的转换器来实现。
import org.eclipse.persistence.jaxb.metadata.MetadataSourceAdapter;
import org.eclipse.persistence.jaxb.xmlmodel.XmlBindings;
import org.eclipse.persistence.jaxb.xmlmodel.XmlSchema;
public class NameTransformerAdapter extends MetadataSourceAdapter {
private XmlBindings bindings;
/**
* @param packageName Fully qualified package name, like {@code com.example.test}
*/
public NameTransformerAdapter(String packageName) {
bindings = new XmlBindings();
bindings.setPackageName(packageName);
bindings.setXmlNameTransformer(XmlNameTransformer.class.getName());
bindings.setXmlSchema(new XmlSchema()); // this is necessary
}
@Override
public XmlBindings getXmlBindings(Map<String, ?> properties, ClassLoader classLoader) {
return bindings;
}
}
引用的变压器非常简单:
import org.eclipse.persistence.oxm.XMLNameTransformer;
public class XmlNameTransformer implements XMLNameTransformer {
/** Uses capitalized name of class */
public String transformTypeName(String name) {
return name.substring(name.lastIndexOf('.') + 1);
}
public String transformElementName(String name) {
return name;
}
public String transformAttributeName(String name) {
return name;
}
public String transformRootElementName(String name) {
return transformTypeName(name);
}
}
包在运行时确定并按如下方式进行跟踪:
List<MetadataSource> adapters = new ArrayList<MetadataSource>();
adapters.add(new NameTransformerAdapter(packageName));
最后,可以使用上述适配器获取 JAXBContext:
import org.eclipse.persistence.jaxb.JAXBContextFactory;
import org.eclipse.persistence.jaxb.JAXBContextProperties;
private JAXBContext getContext(Class<?>[] classes) throws JAXBException {
Map<String, Object> properties = new HashMap<String, Object>();
properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, adapters);
return JAXBContextFactory.createContext(classes, properties);
}
关于java - 用于多个包的 MOXy XmlNameTransformer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22461952/