For example, I\'ve got a simple schema which imports another schema. The second schema (urn:just:attributes, just-attributes.xsd) just defines an attribute group.
I had the same question. In package-info.java
(if you don't have it, you can just manually create it) add the xmlns
part:
@javax.xml.bind.annotation.XmlSchema(xmlns = {
@javax.xml.bind.annotation.XmlNs(namespaceURI = "urn:just:attributes", prefix = "thirdpartyns") },
elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
There is a way of doing this, which uses an internal JAXB implementation class called NamespacePrefixMapper
. In the JAXB RI, this is in com.sun.xml.bind.marshaller
, but in Java6, it's in com.sun.xml.internal.bind.marshaller
.
This is an abstract class, which you can subclass and implement the abstract method which maps namespace URIs on to prefixes.
You then inject an instance of that subclass into the marshaller:
JAXBContext context = ...
Marshaller marshaller = context.createMarshaller();
NamespacePrefixMapper prefixMapper = new MyPrefixMapperImpl();
marshaller.setProperty("com.sun.xml.bind.namespacePrefixMapper", prefixMapper);
The property name is going to be different for the Java6 version, but you get the idea.
Note that this is an internal JAXB implementation class, so there's no guarantee it'll be there in future versions.
http://hwellmann.blogspot.com/2011/03/jaxb-marshalling-with-custom-namespace.html
This shows how to do it.
Another: http://www.systemmobile.com/?p=280
Key bits in case that link dies too:
the NamespacePrefixMapper class, found in the com.sun.xml.bind.marshaller package. The abstract class has one method to implement:
public abstract String getPreferredPrefix(
String namespaceUri,
String suggestion,
boolean requirePrefix);
then
Marshaller marshaller =
jaxbContext.createMarshaller();
marshaller.setProperty(”com.sun.xml.bind.namespacePrefixMapper”,
new MyNamespacePrefixMapper());
If you’re also using javax.xml.xpath.XPath, your NamespacePrefixMapper can also implement javax.xml.namespace.NamespaceContext, centralizing your namespace customization in a single class.
I tested that in Java SE6 and it requires a small change compared to the solution for Java SE 5 (as described above):
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE );
m.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
m.setProperty("com.sun.xml.internal.bind.namespacePrefixMapper", mapper);
So the third property from above contains the additional .internal.
in the package name compared to the Java SE5 version.
What I did not find out yet is how to tell the Marshaller which namespace URI becomes the default namespace (""). If I override the method getPreferredPrefix() and return an empty string, the Marshaller has issues with writing attributes of the default namespace (in this case it creates a new namespace called ns1)