在JAXB编组时删除名称空间前缀

use*_*308 24 namespaces jaxb marshalling prefix

我有从模式创建的JAXB对象.在编组时,xml元素将使用ns2进行注释.我已经尝试过网络上存在的所有选项,但是这些选项都不起作用.我无法修改我的架构或更改package-info.java.请帮忙

Old*_*eon 20

经过大量的研究和修补,我终于设法解决了这个问题.请接受我的道歉,因为没有发布原始参考文献的链接 - 有许多我没有记笔记 - 但这个肯定是有用的.

我的解决方案使用过滤XMLStreamWriter来应用空命名空间上下文.

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;
  }

}
Run Code Online (Sandbox Code Playgroud)

你可以在DelegatingXMLStreamWriter 这里找到.

然后,您可以使用以下方法过滤编组xml:

  // Filter the output to remove namespaces.
  m.marshal(it, NoNamesWriter.filter(writer));
Run Code Online (Sandbox Code Playgroud)

我相信有更有效的机制,但我知道这个有效.

  • 如果你不想使用cxf,导入jaxws-rtxxx.jar然后使用标准jawx-ws通过以下代码执行相同的技巧:class NoNamesWriter扩展XMLStreamWriterFilter, (3认同)

小智 13

对我来说,只更改package-info.java类就像魅力一样,正如zatziky所述:

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;
Run Code Online (Sandbox Code Playgroud)

  • 如果您使用 xjc 通过 .xjb 文件从 xsd 生成 jaxb 工件,则会生成 package-info.java,并且您不应手动更改它。如果使用 Maven 运行 xjc,则可以将 maven-jaxb2-plugi 与 https://github.com/Siggen/jaxb2-namespace-prefix 一起使用。这允许将命名空间前缀添加到 .xjb 文件(这是 xjc 的输入,用于自定义代码的生成方式)。 (2认同)

Ami*_*.io 5

您可以只将命名空间写入一次.您将需要XMLStreamWriter的代理类和package-info.java.然后你将在你的代码中做:

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());
Run Code Online (Sandbox Code Playgroud)

代理类(重要的方法是"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() ...

}
Run Code Online (Sandbox Code Playgroud)

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;
Run Code Online (Sandbox Code Playgroud)