Skip to content
Advertisement

jaxb namespace gives unneeded ns2 prefix

I need to generate the namespace into the xml, but this leads to an inconsistent ns2 prefixing that I don’t need (I don’t have mixed namespaces). I tried several solutions i found with no luck.

package-info.java

    @javax.xml.bind.annotation.XmlSchema(namespace="http://namespace" ,
        elementFormDefault=javax.xml.bind.annotation.XmlNsForm.QUALIFIED,
        xmlns={
        @javax.xml.bind.annotation.XmlNs(namespaceURI="http://namespace", prefix="")
        })

    package hu.xml.create;

POJO

    @XmlRootElement(name = "create", namespace = "http://namespace")
    public class Create{
    ...

marshaller

    public String mashal(Object object) throws JAXBException {
        JAXBContext context = JAXBContext.newInstance(object.getClass());
        Marshaller mar= context.createMarshaller();
        mar.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
    
        StringWriter sw = new StringWriter();

        mar.marshal(object, sw);

        return sw.toString();
}

call

    @RequestMapping("/export/{id}")
    public String export(Model model, @PathVariable(value = "id") Long id) {
        String method = "export";
    
        Create create = new Create(...);
        try {
            String xml = RequestHandler.getInstance().mashal(create);
            model.addAttribute("xml", xml);
        } catch (JAXBException e) {
            e.printStackTrace();
        }
    
        return "export";
}

result

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <ns2:create xmlns:ns2="http://namespace">
        <ns2:tag>
            <subtag>true</subtag>

Advertisement

Answer

The namespace prefix is needed, since you have elements like <subtag> without a namespace. Once you assign a namespace to them, the ns2 prefix will disappear and JAXB will use a default namespace as your required.

There is also a comment in NamespaceContextImpl#declareNsUri of JAXB RI that states:

// the default prefix is already taken.
// move that URI to another prefix, then assign "" to the default prefix.

Edit: If you cannot get rid of the unqualified elements, you can qualify them with the same namespace as the other elements. This is possible at least with JAXB RI and is equivalent to a <xsd:include> tag:

final Map<String, String> props = Collections.singletonMap(JAXBRIContext.DEFAULT_NAMESPACE_REMAP, "http://namespace");
final JAXBContext ctx = JAXBContext.newInstance(new Class[]{Create.class}, props);
Advertisement