6

目前我正在使用以下代码将 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), out);

我想将“hard_coded_namespace”替换为 JAXB“obj”中包含的命名空间(或其属性之一,它们目前应该共享相同的 NS)。

任何想法如何在编组之前获取 NS 信息?在输出流中,出现命名空间。所以他们在“obj”的某个地方。

[更新] 正如下面的答案所指出的,我不需要设置 JAXB_FRAGMENT 属性。我将其更改为:

    JAXB.marshal(new JAXBElement<T>(new QName("hard_coded_namespace", rootName), clazz, jaxbObject), out);
4

5 回答 5

4

目前,这是我找到的解决方案:

    String nsURI = "";
    for(Annotation annotation: jaxbObject.getClass().getPackage().getAnnotations()){
        if(annotation.annotationType() == XmlSchema.class){
            nsURI = ((XmlSchema)annotation).namespace();
            break;
        }
    }

欢迎使用更优雅的解决方案:-)

于 2012-06-11T14:36:33.813 回答
1

你需要使用那个 marshal API 吗?有一个更简单的重载。只要 obj 的运行时类有注解 @XmlRootElement,你应该可以简单地调用

marshaller.marshal(obj, out);
于 2012-06-10T01:03:29.900 回答
1

Marshaller.JAXB_FRAGMENT属性的使用实际上与处理非根元素没有任何关系。它作为一个标志来确定是否应该限制某些封送事件。例如,如果设置了属性,则不会生成开始和结束文档事件。

我没有测试以下内容,但这里有一个关于如何创建一些实用程序代码来查找QName给定 JAXB 对象的基本想法:

  • 如果JAXBIntrospector.isElement返回 true,则只需使用 JAXBIntrospector.getElementName.
  • 使用反射ObjectFactory在与 JAXB 对象相同的包中的类上查找方法,该方法返回JAXBElement并接受一个参数,该参数是与 JAXB 对象相同的类的实例。调用该方法,然后使用JAXBElement.getName.
于 2012-06-11T14:17:03.310 回答
0
JAXBContext jaxbCtx = JAXBContext.newInstance(Instance.class);
QName qname = jaxbCtx.createJAXBIntrospector().getElementName(instance);
于 2015-05-13T17:13:47.957 回答
0

如果要序列化的类上没有@XmlRootElement,则没有其他方法可以查找包声明本身(JAXBIntrospector 将不起作用):

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());
}
于 2017-12-28T12:18:55.730 回答