2012-06-08 83 views
6

目前我編組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), 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

現在,這是我找到了解決辦法:

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

更優雅的解決方案,歡迎:-)

+1

命名空間信息是在'package-info.java' – Chris

+1

取決於你想要你的解決方案是多麼普遍的目的,沒有保證package-info。類將由xjc生成(請參閱-npa選項)。 – kschneid

1

您是否需要使用該編組API?有一個更簡單的超載。只要OBJ的運行時類有註釋@XmlRootElement,你應該能夠簡單地調用

marshaller.marshal(obj, out); 
+0

在這種情況下,我沒有在對象的類中設置XmlRootElement屬性。 Marshaller API是必需的,以便我可以指出這是一個JAXB_FRAGMENT,即一個沒有XmlRootElement的元素。如果我錯了,請糾正我。 – Chris

+0

其實我正在做你推薦的東西。由於中間是新的JAXBElement(),所以很難閱讀...... :-)。 – Chris

1

使用該Marshaller.JAXB_FRAGMENT財產並沒有真正有什麼做處理非根元素。它作爲一個標誌來確定是否應該限制某些編組事件。例如,如果該屬性已設置,則不會生成開始和結束文檔事件。

我沒有測試以下,但這裏的我怎麼會創造出一些實用的代碼來找到一個給定JAXB對象的QName一個基本思想:

  • 如果JAXBIntrospector.isElement返回true,那麼就使用 JAXBIntrospector.getElementName
  • 使用反射來找到在 相同的包作爲一個返回JAXBElement並採取 一個參數是相同的類作爲JAXB 對象的一個​​實例的JAXB對象上的ObjectFactory類的方法。調用該方法,然後使用JAXBElement.getName
+0

感謝您的回答! isElement()在我正在處理的對象上返回false。 – Chris

+1

這很好,第二個項目符號應該覆蓋這個條件... – kschneid

0
JAXBContext jaxbCtx = JAXBContext.newInstance(Instance.class); 
QName qname = jaxbCtx.createJAXBIntrospector().getElementName(instance); 
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()); 
}