2011-04-19 68 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);