Ich habe eine Datei, die mit einem Standardnamensraum gedruckt wird. Die Elemente werden mit einem Präfix von ns2 gedruckt. Ich muss das entfernen, wie es mit meinem Code ist:
<ns2:foo xmlns:ns2="http://namespace" />
wie ich es will:
<foo xmlns="http://namespace" />
so habe ich es codiert, etwas, was, wie ich sehe, für die ns2 ausreichen sollte:
<?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">
...
die generierte Paket-Info stellt sich wie folgt dar:
@javax.xml.bind.annotation.XmlSchema(namespace = "http://namespace",
elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package com.foo.bar;
Ich erstelle die Datei so:
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 ist das Paket, in dem package-info.Java und die Elemente enthalten sind.
Das Foo-Objekt ist definiert und hat folgende Elemente:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"group"
})
@XmlRootElement(name = "Foo")
public class Foo {
@XmlElement(name = "Group", required = true)
protected List<Group> group;
Ist es etwas, was ich vermisst habe? oder habe ich missverstanden, wie das funktioniert?
Wahrscheinlich haben Sie mehrere Namespaces in der Antwort. Hierbei wird die Standardkonvention zum Erstellen von ns # Namespace-Präfixen verwendet, und eines davon wird ohne Präfix zum xmlns. Wenn Sie dies steuern möchten, können Sie Folgendes tun:
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....
Dadurch wird http://namespace
immer als Standard-xmlns festgelegt und ns # für alle anderen Namespaces beim Marshalling verwendet. Sie können ihnen auch beschreibende Präfixe geben, wenn Sie möchten.
Alles was Sie tun müssen, ist, wenn Sie ein neues Paket öffnen
@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 = "") })
Dadurch wird das Präfix ns2 entfernt
Ab JDK6u18 wird die NamespacePrefixMapper-Technik nicht mehr verwendet.
Ich löse dies, indem ich die Datei package-info.Java im Paket jaxb classes lösche und die Anwendung neu kompiliert.
Für Java 8:
Ich ändere den Präfixnamen von 'ns2' nach 'fault'.
Zuerst erstellen Sie Ihren * 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);
}
}
Zweitens , fügen Sie DefaultNamespacePrefixMapper zur Marshaller-Eigenschaft hinzu.
@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);
}
}
Drittens , füge folgende Abhängigkeiten in Gradle/Maven hinzu.
compile 'com.Sun.xml.bind:jaxb-impl:2.2.11'
compile 'com.Sun.xml.bind:jaxb-core:2.2.11'