Christian Eugster
Christian Eugster

Reputation: 41

JAXB: why are defined namespace prefixes not used in generated xml document?

Hi I have generated from an xml schema file (mets.xsd) java classes with xic compiler. This xsd file uses some other namespaces (premis.xsd, ead.xsd ...). To use namespace prefixes I added some annotations to package-info.java file as follows:

@XmlSchema(
    elementFormDefault=XmlNsForm.QUALIFIED,
    location="http://www.loc.gov/mets/mets.xsd",
    namespace="http://www.loc.gov/METS/",
    xmlns=
    {
            @XmlNs(prefix="METS",   namespaceURI="http://www.loc.gov/mets/"),
            @XmlNs(prefix="EAD",    namespaceURI="http://www.loc.gov/ead/"),
            @XmlNs(prefix="PREMIS", namespaceURI="http://www.loc.gov/premis/v2/"),
            @XmlNs(prefix="xlink",  namespaceURI="http://www.w3.org/1999/xlink"),
            @XmlNs(prefix="OAI_DC", namespaceURI="http://www.openarchives.org/OAI/2.0/oai_dc/"),
            @XmlNs(prefix="DC",     namespaceURI="http://purl.org/dc/elements/1.1/")
    }
)
package ch.eugster.herakles.sip.matterhorn.mets;

import jakarta.xml.bind.annotation.XmlNs;
import jakarta.xml.bind.annotation.XmlNsForm;
import jakarta.xml.bind.annotation.XmlSchema;

When I Marshall the java object to xml, I get the following output:

<?xml version="1.0" encoding="UTF-8"?>
<ns1:mets xmlns:METS="http://www.loc.gov/mets/" xmlns:EAD="http://www.loc.gov/ead/" xmlns:PREMIS="http://www.loc.gov/premis/v2/" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:OAI_DC="http://www.openarchives.org/OAI/2.0/oai_dc/" xmlns:DC="http://purl.org/dc/elements/1.1/" xmlns:ns1="http://www.loc.gov/METS/" PROFILE="http://www.docuteam.ch/xmlns/sip-profile.xml">
   <ns1:amdSec/>
   <ns1:fileSec>
      <ns1:fileGrp/>
   </ns1:fileSec>
   <ns1:structMap>
      <ns1:div TYPE="rootfolder" ORDER="1" LABEL="RootFolder_Temp"/>
   </ns1:structMap>
</ns1:mets>

As you see the prefixes are defined correctly but they are not used in the document. Has anyone an idea, what could cause this? Thanks a lot!

Upvotes: 1

Views: 2111

Answers (1)

BATMAN_2008
BATMAN_2008

Reputation: 3540

Even I was facing the same issue (Even after providing the custom prefix to my QName i was getting the default namespace prefix such as ns0,ns1,etc) so I tried a lot of things and finally was able to get it so posting the same here so it can be helpful to you and maybe someone else in the future. You can find my question here

  1. Remove the package-info.java and all of its content (if you have added while trying something).

  2. Since you are using the Moxy you can create a Map with all of the required NamespcaeURI and Prefix. Something like this:

Map<String, String> urisToPrefixes = new HashMap<String, String>();
urisToPrefixes.put("http://www.loc.gov/mets/", "METS");
urisToPrefixes.put("http://www.loc.gov/ead/", "EAD"); 
urisToPrefixes.put("http://www.loc.gov/premis/v2/", "PREMIS"); 
  1. While using the Marshalling approach add the property and send this Map as a parameter:
    marshaller.setProperty(MarshallerProperties.NAMESPACE_PREFIX_MAPPER, urisToPrefixes);

This will ensure that whenever a Namespace is encountered it would check for the respective prefix and add it to the XML header so in this was it would replace all the default prefix ns0,ns1 etc to corresponding prefix from the map.

Complete sample code:

JAXBContext ctx = JAXBContext.newInstance(new Class[] { TestObject.class, SubObject.class });
Map<String, String> urisToPrefixes = new HashMap<String, String>();
urisToPrefixes.put("http://www.loc.gov/mets/", "METS");
urisToPrefixes.put("http://www.loc.gov/ead/", "EAD"); urisToPrefixes.put("http://www.loc.gov/premis/v2/", "PREMIS");
Marshaller m = ctx.createMarshaller();
m.setProperty(MarshallerProperties.NAMESPACE_PREFIX_MAPPER, prefixesToUris);

If you would like to more about this and another approach find the documentation here:

Upvotes: 1

Related Questions