Remove ns2 as default namespace 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.
Remove ns2 prefix while JaxB marshalling an Element without @XmlRootElement annotation
First, you are creating the Foo
element in the wrong namespace. Looking at your desired output, you also want the Foo
element to be in the http://Foo/bar
namespace. To fix this problem, specify that namespace URI when you create the QName
, instead of passing an empty string as the first argument:
// Wrong
QName qName = new QName("", "Foo");
// Right
QName qName = new QName("http://Foo/bar", "Foo");
To get rid of the generated ns2
prefix for the namespace, you need to set the namespace prefix to an empty string. You probably have a package-info.java
file with an @XmlSchema
annotation. It should look like this:
@XmlSchema(namespace = "http://Foo/bar",
elementFormDefault = XmlNsForm.QUALIFIED,
xmlns = @XmlNs(prefix = "", namespaceURI = "http://Foo/bar"))
package com.mycompany.mypackage;
import javax.xml.bind.annotation.XmlNs;
import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;
Note: Setting prefix = ""
will cause JAXB to generate an xmlns
attribute without a generated prefix name such as ns2
in your XML.
jaxb namespace gives unneeded ns2 prefix
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);
How do I remove the ns2 prefixes from XML elements using JAXB 3 and a NamespacePrefixMapper?
I forgot to provide the namespace to the QName :
new QName("http://maven.apache.org/POM/4.0.0", "project")
And now the result looks good :
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<project xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<dependencies>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
</dependencies>
</project>
There's no need for a prefix mapper, so the code can be simplified:
import org.apache.maven.pom.Dependency;
import org.apache.maven.pom.Model;
import org.apache.maven.pom.Model.Dependencies;
import javax.xml.namespace.QName;
import jakarta.xml.bind.JAXB;
import jakarta.xml.bind.JAXBElement;
public class Main {
public static void main(String[] args) {
Model model = new Model();
model.setModelVersion("4.0.0");
model.setDependencies(new Dependencies());
Dependency dependency = new Dependency();
dependency.setGroupId("commons-io");
dependency.setArtifactId("commons-io");
dependency.setVersion("2.11.0");
model.getDependencies().getDependency().add(dependency);
JAXBElement<Model> elem = new JAXBElement<>(new QName("http://maven.apache.org/POM/4.0.0", "project"), Model.class, model);
JAXB.marshal(elem, System.out);
}
}
JAXB Marshallingremove namespace prefix
yes replacing prefix as "empty" seems very tricky as you can see my question here. I did find the solution to do transformation using xslt after the XML generation as below. Hope it helps.
removenamespace.xslt
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:preserve-space elements="*"/>
<xsl:template match="@*|node()[not(self::*)]">
<xsl:copy />
</xsl:template>
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="node()|@*" />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
XSLT transformer
File outputXML = new File(inputXML.getParentFile(), inputXML.getName() + "-ns.xml");
try{
TransformerFactory factory = TransformerFactory.newInstance();
Source xslt = new StreamSource(new File(REMOVE_NAMESPACE_XSL));
Transformer transformer = factory.newTransformer(xslt);
Source text = new StreamSource(inputXML);
transformer.transform(text, new StreamResult(outputXML));
}
catch(Exception e){
// something gone wrong. return original XML.
return inputXML;
}
Related Topics
In Java, How to Combine Two Json Arrays of Objects
Convert Html/Mxml File to Word Doc Programmatically in Java
Reading Data from Nested Json Object Using Java
Spring Webclient: How to Stream Large Byte[] to File
How to Get the Parent Element Name of a Child Element in Json
How to Exit an Android App Programmatically
Java Error Message. Unexpected Type, Required Variable, Found Value
Bottomnavigationview - How to Avoid Recreation of Fragments and Reuse Them
Get Enum Values as List of String in Java 8
How Find Given Number Is Octal or Not
Create List of Object from Another Using Java 8 Streams
Org.Hibernate.Annotationexception: @Onetoone or @Manytoone on <Entity> References an Unknown Entity
How to Combine Date and Time into a Single Object
How to Restart a Java Program Here
How to Find the Number of Times If or Else Code Has Executed
Spring MVC - Get Httpservletresponse Body
Spring Jpa/Hibernate Transaction Force Insert Instead of Update