xmlrootelement xmlns xmlelement remove ns2 namespaceprefixmapper namespace marshaller namespaces jaxb marshalling prefix

namespaces - xmlns - remove ns2 namespace jaxb



Elimine el prefijo de espacio de nombres mientras JAXB se está formando. (5)

Después de mucha investigación y retoques, finalmente logré una solución a este problema. Por favor acepte mis disculpas por no publicar enlaces a las referencias originales (hay muchas y no estaba tomando notas), pero this fue ciertamente útil.

Mi solución utiliza un XMLStreamWriter filtrado que aplica un contexto de espacio de nombres vacío.

public class NoNamesWriter extends DelegatingXMLStreamWriter { private static final NamespaceContext emptyNamespaceContext = new NamespaceContext() { @Override public String getNamespaceURI(String prefix) { return ""; } @Override public String getPrefix(String namespaceURI) { return ""; } @Override public Iterator getPrefixes(String namespaceURI) { return null; } }; public static XMLStreamWriter filter(Writer writer) throws XMLStreamException { return new NoNamesWriter(XMLOutputFactory.newInstance().createXMLStreamWriter(writer)); } public NoNamesWriter(XMLStreamWriter writer) { super(writer); } @Override public NamespaceContext getNamespaceContext() { return emptyNamespaceContext; } }

Puedes encontrar un DelegatingXMLStreamWriter here .

A continuación, puede filtrar el código XML con:

// Filter the output to remove namespaces. m.marshal(it, NoNamesWriter.filter(writer));

Estoy seguro de que hay mecanismos más eficientes, pero sé que este funciona.

Tengo objetos JAXB creados a partir de un esquema. Mientras se realiza el cálculo, los elementos xml se anotan con ns2. He intentado todas las opciones que existen en la red para este problema, pero ninguna de ellas funciona. No puedo modificar mi esquema o cambiar package-info.java. Por favor ayuda


Obtuve el resultado de trabajo al establecer la propiedad:

marshaller.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, "");


Para mí, solo cambiando la clase package-info.java funcionó a la perfección, exactamente como zatziky declaró:

package-info.java

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


Puede dejar que los espacios de nombres se escriban una sola vez. Necesitará una clase proxy de XMLStreamWriter y package-info.java. Entonces lo harás en tu código:

StringWriter stringWriter = new StringWriter(); XMLStreamWriter writer = new Wrapper((XMLStreamWriter) XMLOutputFactory .newInstance().createXMLStreamWriter(stringWriter)); JAXBContext jaxbContext = JAXBContext.newInstance(Collection.class); Marshaller jaxbMarshaller = jaxbContext.createMarshaller(); jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); jaxbMarshaller.marshal(books, writer); System.out.println(stringWriter.toString());

Clase de proxy (el método importante es "writeNamespace"):

class WrapperXMLStreamWriter implements XMLStreamWriter { private final XMLStreamWriter writer; public WrapperXMLStreamWriter(XMLStreamWriter writer) { this.writer = writer; } //keeps track of what namespaces were used so that not to //write them more than once private List<String> namespaces = new ArrayList<String>(); public void init(){ namespaces.clear(); } public void writeStartElement(String localName) throws XMLStreamException { init(); writer.writeStartElement(localName); } public void writeStartElement(String namespaceURI, String localName) throws XMLStreamException { init(); writer.writeStartElement(namespaceURI, localName); } public void writeStartElement(String prefix, String localName, String namespaceURI) throws XMLStreamException { init(); writer.writeStartElement(prefix, localName, namespaceURI); } public void writeNamespace(String prefix, String namespaceURI) throws XMLStreamException { if(namespaces.contains(namespaceURI)){ return; } namespaces.add(namespaceURI); writer.writeNamespace(prefix, namespaceURI); } // .. other delegation method, always the same pattern: writer.method() ... }

package-info.java:

@XmlSchema(elementFormDefault=XmlNsForm.QUALIFIED, attributeFormDefault=XmlNsForm.UNQUALIFIED , xmlns = { @XmlNs(namespaceURI = "http://www.w3.org/2001/XMLSchema-instance", prefix = "xsi")}) package your.package; import javax.xml.bind.annotation.XmlNs; import javax.xml.bind.annotation.XmlNsForm; import javax.xml.bind.annotation.XmlSchema;