JAXB marshalling XMPP stanzas
How about the following?:
Create a custom XMLStreamWriter that will treat all namespace declarations as default namespaces, and then marshal to that:
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;
}
}
}
JAXB marshalling: change element which should declare a namespace
JAXB (JSR-222) does not provide a means to control where namespace declarations occur. JAXB providers tend to put the namespaces on the root element (for performance reasons), but they are not required to.
Below is a link to an answer I gave to a similar question where XMLStreamWriter
is extended to control when the namespace declarations get reported.
- JAXB marshalling XMPP stanzas
Receive custom XMPP stanzas with Smack
If you use PacketExtension
to send custom stanzas, as this thread explained: https://stackoverflow.com/a/6390037/474002
Then, you could use smack api Packet.getExtensions
as the document: http://www.igniterealtime.org/builds/smack/docs/latest/javadoc/org/jivesoftware/smack/packet/Packet.html#getExtensions()
Hope this will help ~
XSD from XML Java Jaxb
This is xxx.xsd, defining the outer element in the foo namespace:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:foo="http://foo.com"
targetNamespace="http://foo.com"
xmlns:bar="http://bar.com"
jaxb:version="2.0">
<xsd:import namespace="http://bar.com"
schemaLocation="yyy.xsd"/>
<xsd:complexType name="DataType">
<xsd:sequence>
<xsd:element ref="bar:childData"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="data" type="foo:DataType"/>
</xsd:schema>
And here is yyy.xsd:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
targetNamespace="http://bar.com"
xmlns:bar="http://bar.com"
jaxb:version="2.0">
<xsd:element name="childData" type="xsd:string"/>
</xsd:schema>
Later The usual Java code for marshalling:
void marshal() throws Exception {
JAXBContext jc = JAXBContext.newInstance( "com.foo:com.bar" );
Marshaller m = jc.createMarshaller();
DataType data = new DataType();
ObjectFactory of = new ObjectFactory();
JAXBElement<DataType> jbe = of.createData(data);
data.setChildData("child data");
m.marshal( jbe, System.out );
}
produces
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:data xmlns="http://bar.com" xmlns:ns2="http://foo.com">
<childData>child data</childData>
</ns2:data>
which is equivalent to the XML you have posted.
XML Marshalling: I want namespace attributes and not prefixes
You can try using NamespacePrefixMapper
. You have to extend it and set it as a property.
Here's an example of the shortest method:
marshaller.setProperty("com.sun.xml.bind.namespacePrefixMapper",
new NamespacePrefixMapper() {
@Override
public String[] getPreDeclaredNamespaceUris() {
return new String[] { MyNamespaces.EXAMPLE_MAIN };
}
@Override
public String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix) {
if (namespaceUri.equals(MyNamespaces.EXAMPLE_MAIN) ||
namespaceUri.equals(MyNamespaces.EXAMPLE_MAIN_RULE))
return "";
}
});
Embedding XML document inside another XML with JAXB
Thanks to Blaise for mention his previous answer. I ended using a similar approach:
This is how I intercepted the Writer:
StringWriter writer = new StringWriter();
XMLOutputFactory factory = XMLOutputFactory.newFactory();
XMLWriter xmlWriter = new XMLWriter(factory.createXMLStreamWriter(writer));
marshaller.marshal(message, xmlWriter);
And here is the XMLWriter class:
import java.util.Iterator;
import javax.xml.namespace.NamespaceContext;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
public class XMLWriter implements XMLStreamWriter {
private XMLStreamWriter writer;
private ProxyNameSpaceContext nc = new ProxyNameSpaceContext();
public XMLWriter(XMLStreamWriter writer) throws XMLStreamException {
super();
this.writer = writer;
writer.setNamespaceContext(nc);
}
@Override
public void close() throws XMLStreamException {
writer.close();
}
@Override
public void flush() throws XMLStreamException {
writer.flush();
}
@Override
public NamespaceContext getNamespaceContext() {
return writer.getNamespaceContext();
}
@Override
public String getPrefix(String uri) throws XMLStreamException {
return writer.getPrefix(uri);
}
@Override
public Object getProperty(String name) throws IllegalArgumentException {
return writer.getProperty(name);
}
@Override
public void setDefaultNamespace(String uri) throws XMLStreamException {
writer.setDefaultNamespace(uri);
}
@Override
public void setNamespaceContext(NamespaceContext context)
throws XMLStreamException {
}
@Override
public void setPrefix(String prefix, String uri) throws XMLStreamException {
writer.setPrefix(prefix, uri);
}
@Override
public void writeAttribute(String prefix, String namespaceURI,
String localName, String value) throws XMLStreamException {
writer.writeAttribute(prefix, namespaceURI, localName, value);
}
@Override
public void writeAttribute(String namespaceURI, String localName,
String value) throws XMLStreamException {
writer.writeAttribute(namespaceURI, localName, value);
}
@Override
public void writeAttribute(String localName, String value)
throws XMLStreamException {
writer.writeAttribute(localName, value);
}
@Override
public void writeCData(String data) throws XMLStreamException {
writer.writeCData(data);
}
@Override
public void writeCharacters(char[] text, int start, int len)
throws XMLStreamException {
writer.writeCharacters(text, start, len);
}
@Override
public void writeCharacters(String text) throws XMLStreamException {
writer.writeCharacters(text);
}
@Override
public void writeComment(String data) throws XMLStreamException {
writer.writeComment(data);
}
@Override
public void writeDTD(String dtd) throws XMLStreamException {
writer.writeDTD(dtd);
}
@Override
public void writeDefaultNamespace(String namespaceURI)
throws XMLStreamException {
writer.writeDefaultNamespace(namespaceURI);
}
@Override
public void writeEmptyElement(String prefix, String localName,
String namespaceURI) throws XMLStreamException {
writer.writeEmptyElement(prefix, localName, namespaceURI);
}
@Override
public void writeEmptyElement(String namespaceURI, String localName)
throws XMLStreamException {
writer.writeEmptyElement(namespaceURI, localName);
}
@Override
public void writeEmptyElement(String localName) throws XMLStreamException {
writer.writeEmptyElement(localName);
}
@Override
public void writeEndDocument() throws XMLStreamException {
writer.writeEndDocument();
}
@Override
public void writeEndElement() throws XMLStreamException {
writer.writeEndElement();
}
@Override
public void writeEntityRef(String name) throws XMLStreamException {
writer.writeEntityRef(name);
}
@Override
public void writeNamespace(String prefix, String namespaceURI)
throws XMLStreamException {
writer.writeNamespace(prefix, namespaceURI);
}
@Override
public void writeProcessingInstruction(String target, String data)
throws XMLStreamException {
writer.writeProcessingInstruction(target, data);
}
@Override
public void writeProcessingInstruction(String target)
throws XMLStreamException {
writer.writeProcessingInstruction(target);
}
@Override
public void writeStartDocument() throws XMLStreamException {
writer.writeStartDocument();
}
@Override
public void writeStartDocument(String encoding, String version)
throws XMLStreamException {
writer.writeStartDocument(encoding, version);
}
@Override
public void writeStartDocument(String version) throws XMLStreamException {
writer.writeStartDocument(version);
}
@Override
public void writeStartElement(String prefix, String localName,
String namespaceURI) throws XMLStreamException {
writer.writeStartElement("", localName, namespaceURI);
if(null != namespaceURI && namespaceURI.length() > 0) {
String currentDefaultNS = nc.getNamespaceURI("");
if(!namespaceURI.equals(currentDefaultNS)) {
writeDefaultNamespace(namespaceURI);
nc.setDefaultNS(namespaceURI);
}
}
}
@Override
public void writeStartElement(String namespaceURI, String localName)
throws XMLStreamException {
writer.writeStartElement(namespaceURI, localName);
}
@Override
public void writeStartElement(String localName) throws XMLStreamException {
writer.writeStartElement(localName);
}
public static class ProxyNameSpaceContext implements NamespaceContext {
private String defaultNS = "";
public void setDefaultNS(String ns) {
defaultNS = ns;
}
@Override
public String getNamespaceURI(String prefix) {
if("".equals(prefix)) {
return defaultNS;
}
return null;
}
@Override
public String getPrefix(String namespaceURI) {
return "";
}
@Override
public Iterator<?> getPrefixes(String namespaceURI) {
return null;
}
}
}
Related Topics
How to Use Jsch for Ssh Key-Based Communication
How to Determine If a Date Is Between Two Dates in Java
Make Arraylist.Toarray() Return More Specific Types
Java Linkedhashmap Get First or Last Entry
Stand-Alone Java Code Formatter/Beautifier/Pretty Printer
Gradle: Could Not Determine Java Version from '11.0.2'
The Simplest Way to Comma-Delimit a List
How to Print Line Numbers to the Log in Java
Flutter Doctor --Android-Licenses Gives a Java Error
Handling Soft-Deletes with Spring JPA
In Java, Is It More Efficient to Use Byte or Short Instead of Int and Float Instead of Double
Case Insensitive String as Hashmap Key
Format File Size as Mb, Gb, etc
Optional Orelse Optional in Java
Why Java.Util.Optional Is Not Serializable, How to Serialize the Object with Such Fields