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); 

这里,Iq和Bind是由相关xmpp模式形成的对象。 我的问题是,使用jaxb 2.0及更高版本,所有命名空间都在根元素中声明:

   resource   

但是,这里需要的是命名空间应该占用适当的位置:

   resource   

有没有办法通过JAXB 2.0或更高版本在第二个xml节中看到它们来编组xmpp节?

长话短说,我在这里有两个问题:1。在适当的位置声明命名空间。 2.删除我理解的命名空间前缀可以使用NamespacePrefixMapper删除? 但不确定,一个例子会很棒。

以下怎么样?:

创建一个自定义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; } } } 

您现在也可以使用自定义映射器控制前缀。

  NamespacePrefixMapper namespacePrefixMapper = new com.sun.xml.bind.marshaller.NamespacePrefixMapper() { private Map 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);