Trifork Blog

Customize namespace prefix when marshalling with Jaxb

February 2nd, 2009 by
|

I was looking a long time on how to set the prefix for a namespace when marshalling an object to xml using JAXB. If you don’t do anything JAXB will write random namespace prefixes (like ns2, ns3).?

Note:
This is a repost of a blog item that was originally posted in the Func knowledge base by Martin Tilma on Februari 2, 2009.

First I found: https://jaxb.dev.java.net/guide/Changing_prefixes.html but with that solution you have to implement an internal abstract class NamespacePrefixMapper.

After re-reading the Javadoc of the Marshaller I found the method marshal(Object jaxbElement, XMLStreamWriter writer) and the XMLStreamWriter interface contains a method setPrefix(String prefix, String uri)

A little code example:

JAXBContext context = JAXBContext.newInstance(object.getClass());

XMLStreamWriter xmlStreamWriter = XMLOutputFactory.newInstance()
.createXMLStreamWriter(writer);
xmlStreamWriter.setPrefix("func", "http://www.func.nl");
Marshaller marshaller = context.createMarshaller();

marshaller.marshal(object, xmlStreamWriter);

update: I have one remaining issue, for some reason the namespace declaration isn’t written to the XML when using setPrefix. If you remove the call to setPrefix it writes the namespace declaration.

update2: After digging around I found that my project has dependency on “WoodSToX XML-processor” which specifies its own XMLOutputFactory (see the META-INF/services directory in the jar).

To fix my issue I wrote a XMLStreamWriter wrapper that calls writeNamespace(String prefix, String namespaceURI) to write the declaration.

The attachment (MarshalUtil.java_.txt) contains a utility class to marshal and unmarshal.

4 Responses

  1. July 24, 2009 at 21:53 by Anonymous

    Hello… Friend, i have generated some classes with JAXB 2.1, using the Schema (.XSD)…

    Some class when i do the marshal goes OK, but classes appears the namespace NS2….
    here the XML generated:

    2
    INUTILIZAR
    53
    09
    00000000123456
    55
    123
    101
    111
    Falha no Sistema

    But see need looks like:

    2
    INUTILIZAR
    53
    09
    00000000123456
    55
    123
    101
    111
    Falha no Sistema

    Please, i need

  2. July 24, 2009 at 21:55 by Anonymous

    Sorry…. the xml code shows mask here…
    Please, can i get some help yours?

    Thanks

  3. July 28, 2009 at 09:16 by Martin Tilma

    Hi,

    We use “package-info.java” containing annotations to fix the namespaces in the XML.

    please see: https://jaxb.dev.java.net/tutorial/section_6_2_3-Annotations-for-the-Schema-XmlSchema.html#Annotations%20for%20the%20Schema:%20XmlSchema

  4. April 14, 2011 at 10:30 by jawahar prabhu

    hi, we can try with this..

    import java.util.ListIterator;

    import org.dom4j.Document;
    import org.dom4j.Element;
    import org.dom4j.Namespace;
    import org.dom4j.QName;
    import org.dom4j.Visitor;
    import org.dom4j.VisitorSupport;
    import org.dom4j.io.SAXReader;

    public class VisitorExample {

    public static void main(String[] args) throws Exception {
    Document doc = new SAXReader().read(“test.xml”);
    Namespace oldNs = Namespace.get(“oldNamespace”);
    Namespace newNs = Namespace.get(“newPrefix”, “newNamespace”);
    Visitor visitor = new NamesapceChangingVisitor(oldNs, newNs);
    doc.accept(visitor);
    System.out.println(doc.asXML());
    }
    }

    class NamesapceChangingVisitor extends VisitorSupport {
    private Namespace from;
    private Namespace to;

    public NamesapceChangingVisitor(Namespace from, Namespace to) {
    this.from = from;
    this.to = to;
    }

    public void visit(Element node) {
    Namespace ns = node.getNamespace();

    if (ns.getURI().equals(from.getURI())) {
    QName newQName = new QName(node.getName(), to);
    node.setQName(newQName);
    }

    ListIterator namespaces = node.additionalNamespaces().listIterator();
    while (namespaces.hasNext()) {
    Namespace additionalNamespace = (Namespace) namespaces.next();
    if (additionalNamespace.getURI().equals(from.getURI())) {
    namespaces.remove();
    }
    }
    }

    }