JAXB che esegue il marshalling delle stanze XMPP

Sto tentando di eseguire il marshalling di un messaggio utilizzando il seguente frammento:

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

Qui, Iq e Bind sono gli oggetti formati dagli schemi xmpp rilevanti. Il mio problema è che con jaxb 2.0 e versioni successive, tutti gli spazi dei nomi sono dichiarati nell’elemento root:

   resource   

Ma qui è necessario che gli spazi dei nomi occupino i luoghi appropriati:

   resource   

C’è un modo per eseguire il marshalling delle stanze xmpp come le vedi nella seconda stanza xml attraverso JAXB 2.0 o versioni successive?

Per farla breve, ho 2 problemi qui: 1. Dichiarare gli spazi dei nomi nelle posizioni appropriate. 2. rimuovendo il prefisso del namespace che capisco può essere rimosso usando NamespacePrefixMapper? Non sono sicuro, un esempio sarebbe grandioso.

    Che ne dici dei seguenti ?:

    Creare un XMLStreamWriter personalizzato che tratterà tutte le dichiarazioni dello spazio dei nomi come spazi dei nomi predefiniti, quindi eseguirà il marshalling su di esso:

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

    Al giorno d’oggi puoi controllare i prefissi anche usando un mappatore personalizzato.

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