简体   繁体   中英

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?

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

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.

从 JDK6u18 开始,不再使用 NamespacePrefixMapper 技术。

我解决了这个问题,将文件 package-info.java 删除到 jaxb classes 包中并重新编译应用程序。

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'

更改 elementFormDefault="unqualified" 中的属性值

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

Remove namespace from @XmlRootElement

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

After: @XmlRootElement(name = "XXX")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM