Paul Taylor
Paul Taylor

Reputation: 13190

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

Upvotes: 2

Views: 2314

Answers (3)

DLight
DLight

Reputation: 1826

For the case where you produced your java classes with xjc or simply don't want to use annotations directly, you can do it via a MOXy binding file (oxm):

<?xml version="1.0"?>
<xml-bindings
  xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
  package-name="your.package.name">

  <xml-schema
    namespace="http://yournamespace">
    <xml-ns
      prefix=""
      namespace-uri="http://yournamespace">
    </xml-ns>
  </xml-schema>
</xml-bindings>

It's the equivalent of what Blaise proposed in his post in the package-info.

See this answer for how to use the external binding file.

Upvotes: 0

bdoughan
bdoughan

Reputation: 148977

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.

Upvotes: 3

Ian Roberts
Ian Roberts

Reputation: 122364

Rather than use the JAXBContextFactory directly, just create a file named jaxb.properties containing the line

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

and put it in the same directory as your Metadata.java, then JAXBContext.newInstance("org.musicbrainz.mmd2") will use the EclipseLink JAXB implementation automatically.

Upvotes: 1

Related Questions