Vegard
Vegard

Reputation: 1922

Remove ns2 as default namespace prefix

I have a file that is printed with a default namespace. The elements are printed with a prefix of ns2, I need this to be removed, how it is with my code:

<ns2:foo xmlns:ns2="http://namespace" />

how I want it to be:

<foo xmlns="http://namespace" />

this is how I have coded it, something which as I see it should be enough for the ns2 to go away:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:bar="http://namespace" targetNamespace="http://namespace"
    elementFormDefault="qualified">
...

the generated package-info turns out like this:

@javax.xml.bind.annotation.XmlSchema(namespace = "http://namespace", 
    elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package com.foo.bar;

I create the file like this:

JAXBContext jaxbContext = JAXBContext.newInstance(generatedClassesPackage);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.marshal(new JAXBElement<Foo>(new QName("http://namespace", "Foo"),
Foo.class, rootFoo), outputStream);

generatedClassesPackage is the package where package-info.java and the elements are.

The Foo object is defined and has elements like this::

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "group"
})
@XmlRootElement(name = "Foo")
public class Foo {

    @XmlElement(name = "Group", required = true)
    protected List<Group> group;

Is it something I have missed? or have I misunderstood how this works?

Upvotes: 40

Views: 93153

Answers (8)

Andriy
Andriy

Reputation: 2101

For example, if you want to generate

<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.03" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

You need to create such package-info.java class in the same package with your JAXB pojo classes.

@XmlSchema(namespace = "http://www.w3.org/2001/XMLSchema-instance",
    elementFormDefault = XmlNsForm.QUALIFIED,
    xmlns = @XmlNs(prefix = "", namespaceURI = "urn:iso:std:iso:20022:tech:xsd:pain.001.001.03"))
package com.amway.instantpayments.bankfileservice.jaxb.pojo;

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

And pay attention, if you will specify namespace as "urn:iso:std:iso:20022:tech:xsd:pain.001.001.03" and namespaceURI as "http://www.w3.org/2001/XMLSchema-instance" you will get

ns2:Document xmlns:ns2="urn:iso:std:iso:20022:tech:xsd:pain.001.001.03" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

Upvotes: 2

Deepak Surthi
Deepak Surthi

Reputation: 1

Remove namespace from @XmlRootElement

Before: XmlRootElement(name = "XXX", namespace = "abc.xsd")

After: @XmlRootElement(name = "XXX")

Upvotes: 0

Saurabh Bhurle
Saurabh Bhurle

Reputation: 169

Change the attribute value of elementFormDefault="unqualified" in

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:bar="http://namespace" targetNamespace="http://namespace" elementFormDefault="qualified">

Upvotes: 1

Vladimir
Vladimir

Reputation: 555

For Java 8:

I chagnge prefix name from 'ns2' to 'fault'.

Firstly, create your *DefaultNamespacePrefixMapper *.

import com.sun.xml.bind.marshaller.NamespacePrefixMapper;
import java.util.HashMap;
import java.util.Map;

public class DefaultNamespacePrefixMapper extends NamespacePrefixMapper {

    private static final String FAULT_PREFIX = "fault";

    private Map<String, String> namespaceMap = new HashMap<>();

    public DefaultNamespacePrefixMapper() {
        this.namespaceMap.put(NAMESPACE, FAULT_PREFIX);
    }

    @Override
    public String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix) {
        return namespaceMap.getOrDefault(namespaceUri, suggestion);
    }
}

Secondy, add your DefaultNamespacePrefixMapper to Marshaller property.

@SuppressWarnings("unchecked")
private <T> void returnFault(T fault, SoapFault soapFault) {
    try {
        JAXBContext jaxbContext = JAXBContext.newInstance(fault.getClass());
        QName name = new QName(NAMESPACE, fault.getClass().getSimpleName());
        JAXBElement<T> element = new JAXBElement<>(name, (Class<T>) fault.getClass(), fault);

        Marshaller marshaller = jaxbContext.createMarshaller();
        marshaller.setProperty("com.sun.xml.bind.namespacePrefixMapper", new DefaultNamespacePrefixMapper());
        marshaller.marshal(element, soapFault.addFaultDetail().getResult());
    } catch (JAXBException e) {
        log.error("Exception when marshalling SOAP fault.", e);
    }
}

Thirdly, add following dependencies in gradle/maven.

compile 'com.sun.xml.bind:jaxb-impl:2.2.11'
compile 'com.sun.xml.bind:jaxb-core:2.2.11'

Upvotes: 0

Diego Maye
Diego Maye

Reputation: 327

I solve this deleting the file package-info.java into the jaxb classes package and re-compiling the application.

Upvotes: 5

yonia
yonia

Reputation: 1741

All you need 2 do is when you open a new package select create package info in the package info add the following annotation or change it as needed

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

This will remove the ns2 prefix

Upvotes: 35

s332401890
s332401890

Reputation: 121

Beginning from JDK6u18 the NamespacePrefixMapper technique is not used anymore.

Upvotes: 7

Daniel Moses
Daniel Moses

Reputation: 5858

Most likely you have multiple namespaces in the response. This will use the default convention of creating ns# namespace prefixes and one of them becomes the xmlns without a prefix. If you want to control this you can do the following:

NamespacePrefixMapper mapper = new NamespacePrefixMapper() {
        public String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix) {
            if ("http://namespace".equals(namespaceUri) && !requirePrefix)
                return "";
            return "ns";
        }
    };
    marshaller.setProperty("com.sun.xml.bind.namespacePrefixMapper", mapper);
    marshaller.mashal....

This will set the http://namespace as the default xmlns always and use ns# for all other namespaces when marshalling. You can also give them more descriptive prefixes if you want.

Upvotes: 12

Related Questions