2011-04-19 62 views
3

我想馬歇爾用下面的代碼片段的消息:JAXB編組XMPP節

 JAXBContext jContext = JAXBContext.newInstance(Iq.class); 
     Marshaller m = newJAXBContext.createMarshaller(); 
     m.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE); 
     m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 

     Bind bind = new Bind(); 
     bind.setResource("resource"); 
     Iq iq = new Iq(); 
     iq.setId(iqId); 
     iq.setType("set"); 
     iq.getAnies().add(bind); 

     ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
     m.marshal(iq, baos); 

這裏,智商和綁定是從相關的XMPP架構形成的對象。我的問題是,與JAXB 2.0和更高版本中,所有的命名空間聲明中的根元素:

<iq from='[email protected]/balcony' 
    id='rg1' 
    type='get' xmlns='jabber:client' xmlns:ns1='urn:ietf:params:xml:ns:xmpp-bind'> 
    <ns1:bind> 
     <ns1:resource>resource</ns1:resource> 
    </ns1:bind> 
</iq> 

但是,這裏需要的是,命名空間應占有適當的地方:

<iq from='[email protected]/balcony' 
    id="rg1" 
    type="get" xmlns="jabber:client"> 
     <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"> 
      <resource>resource</resource> 
     </bind> 
</iq> 

有沒有一種方法來編組xmpp節,就像您在第2個xml節中通過JAXB 2.0或更高版本看到的那樣?

長話短說,我在這裏有兩個問題: 1.在適當的位置聲明命名空間。 2.刪除我明白的命名空間前綴可以使用NamespacePrefixMapper刪除?不知道,但一個例子會很好。

+0

假設命名空間在使用之前被聲明,它在聲明的位置並不重要。沒有「合適的地點」。 – 2011-04-19 17:57:41

+0

但似乎我正在使用的XMPP服務器似乎沒有響應消息,如果名稱空間擠在根元素。我相信它期望命名空間被放在單個標籤上。 – 2011-04-19 18:05:41

回答

5

如何以下?:

創建一個自定義XMLStreamWriter將處理所有的名稱空間聲明爲默認命名空間,然後元帥說:

ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
XMLOutputFactory xof = XMLOutputFactory.newFactory(); 
XMLStreamWriter xsw = xof.createXMLStreamWriter(System.out); 
xsw = new MyXMLStreamWriter(xsw); 
m.marshal(iq, xsw); 
xsw.close(); 

MyXMLStreamWriter

import java.util.Iterator; 

import javax.xml.namespace.NamespaceContext; 
import javax.xml.stream.XMLStreamException; 
import javax.xml.stream.XMLStreamWriter; 

public class MyXMLStreamWriter implements XMLStreamWriter { 

    private XMLStreamWriter xsw; 
    private MyNamespaceContext nc = new MyNamespaceContext(); 

    public MyXMLStreamWriter(XMLStreamWriter xsw) throws Exception { 
     this.xsw = xsw; 
     xsw.setNamespaceContext(nc); 
    } 

    public void close() throws XMLStreamException { 
     xsw.close(); 
    } 

    public void flush() throws XMLStreamException { 
     xsw.flush(); 
    } 

    public NamespaceContext getNamespaceContext() { 
     return xsw.getNamespaceContext(); 
    } 

    public String getPrefix(String arg0) throws XMLStreamException { 
     return xsw.getPrefix(arg0); 
    } 

    public Object getProperty(String arg0) throws IllegalArgumentException { 
     return xsw.getProperty(arg0); 
    } 

    public void setDefaultNamespace(String arg0) throws XMLStreamException { 
     xsw.setDefaultNamespace(arg0); 
    } 

    public void setNamespaceContext(NamespaceContext arg0) throws XMLStreamException { 
    } 

    public void setPrefix(String arg0, String arg1) throws XMLStreamException { 
     xsw.setPrefix(arg0, arg1); 
    } 

    public void writeAttribute(String arg0, String arg1) throws XMLStreamException { 
     xsw.writeAttribute(arg0, arg1); 
    } 

    public void writeAttribute(String arg0, String arg1, String arg2) throws XMLStreamException { 
     xsw.writeAttribute(arg0, arg1, arg2); 
    } 

    public void writeAttribute(String arg0, String arg1, String arg2, String arg3) throws XMLStreamException { 
     xsw.writeAttribute(arg0, arg1, arg2, arg3); 
    } 

    public void writeCData(String arg0) throws XMLStreamException { 
     xsw.writeCData(arg0); 
    } 

    public void writeCharacters(String arg0) throws XMLStreamException { 
     xsw.writeCharacters(arg0); 
    } 

    public void writeCharacters(char[] arg0, int arg1, int arg2) throws XMLStreamException { 
     xsw.writeCharacters(arg0, arg1, arg2); 
    } 

    public void writeComment(String arg0) throws XMLStreamException { 
     xsw.writeComment(arg0); 
    } 

    public void writeDTD(String arg0) throws XMLStreamException { 
     xsw.writeDTD(arg0); 
    } 

    public void writeDefaultNamespace(String arg0) throws XMLStreamException { 
     xsw.writeDefaultNamespace(arg0); 
    } 

    public void writeEmptyElement(String arg0) throws XMLStreamException { 
     xsw.writeEmptyElement(arg0); 
    } 

    public void writeEmptyElement(String arg0, String arg1) throws XMLStreamException { 
     xsw.writeEmptyElement(arg0, arg1); 
    } 

    public void writeEmptyElement(String arg0, String arg1, String arg2) throws XMLStreamException { 
     xsw.writeEmptyElement(arg0, arg1, arg2); 
    } 

    public void writeEndDocument() throws XMLStreamException { 
     xsw.writeEndDocument(); 
    } 

    public void writeEndElement() throws XMLStreamException { 
     xsw.writeEndElement(); 
    } 

    public void writeEntityRef(String arg0) throws XMLStreamException { 
     xsw.writeEntityRef(arg0); 
    } 

    public void writeNamespace(String arg0, String arg1) throws XMLStreamException { 
    } 

    public void writeProcessingInstruction(String arg0) throws XMLStreamException { 
     xsw.writeProcessingInstruction(arg0); 
    } 

    public void writeProcessingInstruction(String arg0, String arg1) throws XMLStreamException { 
     xsw.writeProcessingInstruction(arg0, arg1); 
    } 

    public void writeStartDocument() throws XMLStreamException { 
     xsw.writeStartDocument(); 
    } 

    public void writeStartDocument(String arg0) throws XMLStreamException { 
     xsw.writeStartDocument(arg0); 
    } 

    public void writeStartDocument(String arg0, String arg1) throws XMLStreamException { 
     xsw.writeStartDocument(arg0, arg1); 
    } 

    public void writeStartElement(String arg0) throws XMLStreamException { 
     xsw.writeStartElement(arg0); 
    } 

    public void writeStartElement(String arg0, String arg1) throws XMLStreamException { 
     xsw.writeStartElement(arg0, arg1); 
    } 

    public void writeStartElement(String arg0, String arg1, String arg2) throws XMLStreamException { 
     xsw.writeStartElement("", arg1, arg2); 
     if(null != arg2 || arg2.length() > 0) { 
      String currentDefaultNS = nc.getNamespaceURI(""); 
      if(!arg2.equals(currentDefaultNS)) { 
       writeDefaultNamespace(arg2); 
       nc.setDefaultNS(arg2); 
      } 
     } 
    } 

    private static class MyNamespaceContext implements NamespaceContext { 

     private String defaultNS = ""; 

     public void setDefaultNS(String ns) { 
      defaultNS = ns; 
     } 

     public String getNamespaceURI(String arg0) { 
      if("".equals(arg0)) { 
       return defaultNS; 
      } 
      return null; 
     } 

     public String getPrefix(String arg0) { 
      return ""; 
     } 

     public Iterator getPrefixes(String arg0) { 
      return null; 
     } 

    } 
} 
+0

Blaise,你知道XMLOutputFactory和XMLStreamWriter是否線程安全嗎?我試圖在網上找到答案,但找不到可靠的資源。 – 2011-04-19 22:58:03

1

您現在可以使用自定義映射器控制前綴。

NamespacePrefixMapper namespacePrefixMapper = new com.sun.xml.bind.marshaller.NamespacePrefixMapper() { 

     private Map<String, String> prefixes; 

     { 
      prefixes = new HashMap<>(3); 
      prefixes.put(XMLConstants.XML_NS_URI, XMLConstants.XML_NS_PREFIX); 
      prefixes.put(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "xsi"); 
      prefixes.put(XMLConstants.W3C_XML_SCHEMA_NS_URI, "xs"); 
      prefixes.put(WellKnownNamespace.XML_MIME_URI, "xmime"); 
     } 

     @Override 
     public String getPreferredPrefix(String namespaceUri, String suggestion, 
      boolean requirePrefix) { 
      String prefix = suggestion == null ? prefixes.get(namespaceUri) 
       : suggestion; 
      return prefix == null ? XMLConstants.DEFAULT_NS_PREFIX : prefix; 
     } 

    }; 
    marshaller.setProperty("com.sun.xml.bind.namespacePrefixMapper", 
     namespacePrefixMapper);