Search code examples
xmljaxbeclipselinkmoxy

How do I get EclipseLink JAXB (MOXy) to not display namespaces in XML output


I'm trying to move from the JAXB reference implementation to EclipseLink JAXB (MOXy) because it appears to solve JAXB outputting invalid XML when data contains non-displayable chars but I have a problem with it displaying namespace tags.

This is how I create a JAXBContext

return JAXBContext.newInstance("org.musicbrainz.mmd2");

and this is the output I get

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <metadata created="2013-02-27T12:12:13.305Z" 
        xmlns="http://musicbrainz.org/ns/mmd-2.0#" 
        xmlns:ext="http://musicbrainz.org/ns/ext#-2.0">
        <annotation-list count="1" offset="0">
            <annotation type="release" ext:score="100">
                <entity>bdb24cb5-404b-4f60-bba4-7b730325ae47</entity>
                <name>Pieds nus sur la braise</name>
                <text>EAN: 0828768226629 - DiscID: TWj6cLku360MfFYAq_MEaT_stgc-</text>
            </annotation>
        </annotation-list>
    </metadata>

I'm trying to get same output with EclipseLink MOXy, I get context as follows

 Map<String, Object> properties = new HashMap<String, Object>(1);
 properties.put(JAXBContextProperties.MEDIA_TYPE, "application/xml");
 return JAXBContextFactory.createContext(new Class[]{Metadata.class}, properties);

and this generates

<?xml version="1.0" encoding="UTF-8"?>
<ns0:metadata 
   xmlns:ns0="http://musicbrainz.org/ns/mmd-2.0#" 
   xmlns:ext="http://musicbrainz.org/ns/ext#-2.0" 
   created="2013-02-27T12:11:35.511Z">
   <ns0:annotation-list count="1" offset="0">
      <ns0:annotation type="release" ext:score="100">
         <ns0:entity>bdb24cb5-404b-4f60-bba4-7b730325ae47</ns0:entity>
         <ns0:name>Pieds nus sur la braise</ns0:name>
         <ns0:text>EAN: 0828768226629 - DiscID: TWj6cLku360MfFYAq_MEaT_stgc-</ns0:text>
      </ns0:annotation>
   </ns0:annotation-list>
</ns0:metadata>

I don't want the ns0 stuff, can I get rid of it


Solution

  • ISSUE #1 - USE THE DEFAULT NAMESPACE

    package-info

    We will use the package level @XmlSchema annotation to specify the namespace qualification. We will also suggest that no prefix be used for the http://musicbrainz.org/ns/mmd-2.0# namespace and and that the ext prefix be used for the http://musicbrainz.org/ns/ext#-2.0" namespace.

    @XmlSchema(
        namespace="http://musicbrainz.org/ns/mmd-2.0#",
        xmlns={
            @XmlNs(namespaceURI="http://musicbrainz.org/ns/mmd-2.0#", prefix=""),
            @XmlNs(namespaceURI = "http://musicbrainz.org/ns/ext#-2.0", prefix = "ext")
        }
    )
    package forum15111903;
    
    import javax.xml.bind.annotation.*;
    

    Metadata

    No namespace information has to be included on your domain model for the http://musicbrainz.org/ns/mmd-2.0# as it will be applied to all elements in this package by default.

    package forum15111903;
    
    import javax.xml.bind.annotation.*;
    import javax.xml.datatype.XMLGregorianCalendar;
    
    @XmlRootElement
    @XmlAccessorType(XmlAccessType.FIELD)
    public class Metadata {
    
        @XmlAttribute
        private XMLGregorianCalendar created;
    
    }
    

    For More Information


    ISSUE #2 - BOOTSTRAPPING MOXy as the JAXB (JSR-222) PROVIDER

    Option #1 - Using the Standard JAXB APIs

    You can include a file called jaxb.properties in the same package as your model classes with the following entry (see: http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html):

    javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
    

    Then you can bootstrap your JAXBContext as follows:

    package forum15111903;
    
    import java.io.File;
    import javax.xml.bind.*;
    
    public class Demo {
    
        public static void main(String[] args) throws Exception {
            JAXBContext jc = JAXBContext.newInstance(Metadata.class);
    
            Unmarshaller unmarshaller = jc.createUnmarshaller();
            File xml = new File("src/forum15111903/input.xml");
            Metadata metadata = (Metadata) unmarshaller.unmarshal(xml);
    
            Marshaller marshaller = jc.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshaller.marshal(metadata, System.out);
        }
    
    }
    

    Option #2 - Using MOXy's Native APIs

    If you don't want to use a jaxb.properties file then you can leverage the MOXy JAXBContextFactory class and do the following:

    package forum15111903;
    
    import java.io.File;
    import javax.xml.bind.*;
    import org.eclipse.persistence.jaxb.JAXBContextFactory;
    
    public class Demo {
    
        public static void main(String[] args) throws Exception {
            JAXBContext jc = JAXBContextFactory.createContext(new Class[] {Metadata.class}, null);
    
            Unmarshaller unmarshaller = jc.createUnmarshaller();
            File xml = new File("src/forum15111903/input.xml");
            Metadata metadata = (Metadata) unmarshaller.unmarshal(xml);
    
            Marshaller marshaller = jc.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshaller.marshal(metadata, System.out);
        }
    
    }
    

    ISSUE #3 - properties.put(JAXBContextProperties.MEDIA_TYPE, "application/xml");

    The default media type for MOXy is application/xml, you can use this property to specify application/json to get JSON ouput.