Java 如何获取JAXB对象的名称空间
目前,我正在使用以下代码将JAXB对象编组到输出流Java 如何获取JAXB对象的名称空间,java,namespaces,jaxb,Java,Namespaces,Jaxb,目前,我正在使用以下代码将JAXB对象编组到输出流 marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE); ByteArrayOutputStream out = new ByteArrayOutputStream(); marshaller.marshal(new JAXBElement(new QName("hard_coded_namespace", clazz.getSimpleName()), clazz, obj
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
ByteArrayOutputStream out = new ByteArrayOutputStream();
marshaller.marshal(new JAXBElement(new QName("hard_coded_namespace", clazz.getSimpleName()), clazz, obj), out);
我想用JAXB“obj”中包含的名称空间替换“硬编码的名称空间”(或者它的一个属性,它们当前应该共享相同的NS)
你知道如何在编组前获取NS信息吗?在输出流中,将显示名称空间。所以他们在“obj”的某个地方
[更新]正如下面的答案所指出的,我不需要设置JAXB_片段属性。我把它改成:
JAXB.marshal(new JAXBElement<T>(new QName("hard_coded_namespace", rootName), clazz, jaxbObject), out);
JAXB.marshall(新的JAXBElement(新的QName(“硬编码的名称空间”,rootName),clazz,jaxbObject),out);
您需要使用封送处理API吗?还有一个更简单的重载。只要obj的运行时类具有注释@XmlRootElement,您就应该能够简单地调用
marshaller.marshal(obj, out);
Marshaller.JAXB_FRAGMENT
属性的使用实际上与处理非根元素无关。它充当一个标志,以确定是否应限制某些封送处理事件。例如,如果设置了属性,则不会生成开始和结束文档事件
我还没有测试以下内容,但下面是如何创建一些实用程序代码来查找给定JAXB对象的QName
的基本想法:
- 如果
返回true,则只需使用JAXBIntrospector.isElement
JAXBIntrospector.getElementName
- 使用反射在中的
类上查找方法 与返回ObjectFactory
并获取 与JAXB是同一类的实例的单个参数 对象调用该方法,然后使用JAXBElement
JAXBElement.getName
String nsURI = "";
for(Annotation annotation: jaxbObject.getClass().getPackage().getAnnotations()){
if(annotation.annotationType() == XmlSchema.class){
nsURI = ((XmlSchema)annotation).namespace();
break;
}
}
欢迎使用更优雅的解决方案:-)如果类上没有要序列化的@XmlRootElement,则没有其他方法来查找包声明本身(JAXBIntrospector将不起作用):
private QName getQName(最终类clazz){
//没有其他方法,因为它不是@RootXmlElement
最终字符串xmlns;
最终包apapackage=clazz.getPackage();
if(aPackage.isAnnotationPresent(XmlSchema.class)){
xmlns=aPackage.getDeclaredAnnotation(XmlSchema.class).namespace();
}否则{
xmlns=”“;//可能抛出非法
}
返回新的QName(xmlns,clazz.getSimpleName());
}
在这种情况下,我没有在对象的类中设置XmlRootElement属性。Marshaller API是必需的,因此我可以指出这是一个JAXB_片段,即没有XmlRootElement的元素。如果我错了,请纠正我。实际上我正按照你的建议做。因为新的JAXBelEnter()在中间……-很难阅读。命名空间信息位于package info.java
中,这取决于您希望解决方案的通用性,不能保证package-info.class将由xjc生成(请参见-npa选项)。感谢您的回答!isElement()在我处理的对象上返回false。
JAXBContext jaxbCtx = JAXBContext.newInstance(Instance.class);
QName qname = jaxbCtx.createJAXBIntrospector().getElementName(instance);
private <T> QName getQName(final Class<T> clazz) {
// No other way since it is not @RootXmlElement
final String xmlns;
final Package aPackage = clazz.getPackage();
if (aPackage.isAnnotationPresent(XmlSchema.class)) {
xmlns = aPackage.getDeclaredAnnotation(XmlSchema.class).namespace();
} else {
xmlns = ""; // May throw illegal
}
return new QName(xmlns, clazz.getSimpleName());
}