Jaxb Marshalling Xmpp Stanzas

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



Leave a reply



Submit