xml - JAXB 和命名空间相关问题

标签 xml namespaces jaxb moxy jaxb2

在编码 JAXB 类后,我有以下 XML:

<?xml version="1.0" encoding="UTF-8"?>
<foo:Object xsi:schemaLocation="http://foo.com/ http://foo.com/foo.xsd" 
xmlns:ns0="http://lipsum.com/bar" xmlns:foo="http://foo.com/" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <foo:Some attr1="601"/>
   <foo:Others>
      <bar:Another xsi:schemaLocation="http://lipsum.com/bar 
      http://lipsum.com/bar.xsd" xmlns:bar="http://lipsum.com/bar">
         <bar:SomeOther attr2="01"/>
      </bar:Another>
  </foo:Others>
</foo:Object>

jaxb 类中的 元素声明为:
    @XmlAnyElement(lax = true)
    @XmlElementRefs({
         @XmlElementRef(name="Another", type=Another.class, required=false)
    })
    protected List<Object> any;

它可能包含未知数量的其他具有自己命名空间的元素。

问题:

当我编码 Some.class 对象时,jaxb 将 Another.class 的命名空间作为 ns0 放入根元素中,因为我从另一个方法中将 编码为 Element,我不需要它再次进入根元素。

这是一个问题,因为 不是必需的,所以如果我用空列表编码 Some.class 对象,我将始终拥有 xmlns:ns0。

我需要 @XmlElementRefs 和 @XmlElementRef 注释,因为我需要从 json 转换为 XML,而 Jackson 需要知道“任何”列表可能具有的类型。

我如何告诉 JAXB Oracle/Moxy 实现:
1.- Ignore the namespaces from @XmlElementRef classes during the marshalling.
2.- Remove the not used namespaces aka NS[0-9] prefixes from the root element.

任何帮助将不胜感激。

最佳答案

以防万一有人需要这个,我有办法删除不需要的命名空间,这个技巧是从 XMLStreamWriter 提供的

步骤 1.- 创建一个 WrapperXMLStreamWriter 类,用于包装 XMLStreamWriter。

public class WrapperXMLStreamWriter implements XMLStreamWriter {
    private final XMLStreamWriter writer;

    public WrapperXMLStreamWriter(XMLStreamWriter writer) {
        this.writer = writer;
    }

    /* (non-Javadoc)
     * @see javax.xml.stream.XMLStreamWriter#writeStartElement(java.lang.String)
     */
    @Override
    public void writeStartElement(String localName) throws XMLStreamException {
        // for each overloaded method call to writer do the method
        writer.writeStartElement(localName);
    }

     /* (non-Javadoc)
     * @see javax.xml.stream.XMLStreamWriter#writeNamespace(java.lang.String, java.lang.String)
     */
    @Override
    public void writeNamespace(String prefix, String namespaceURI) throws XMLStreamException {
        // Here is the trick
        if(!prefix.startsWith("ns")){
            writer.writeNamespace(prefix, namespaceURI);
        }
    }

    ...
}

步骤 2.- 像往常一样创建编码器
Map<String,String> prefixes = new HashMap<String, String>();

// 
prefixes.put("http://www.w3.org/2001/XMLSchema-instance","xsi");
prefixes.put("http://foo.com/", "foo");

Marshaller marshaller =  AppContextTool.getInstance().getContextForFoo().createMarshaller();

// 
marshaller.setProperty("com.sun.xml.bind.namespacePrefixMapper", new NamespacePrefixMapperImpl(prefixes));
marshaller.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, "http://foo.com/ http://foo.com/foo.xsd");

3.- 使用第一步的给定 XMLStreamWriter 编码 Foo 实例
Foo foo = new Foo();

ByteArrayOutputStream xml= new ByteArrayOutputStream();
try {
    XMLStreamWriter writer = 
                new WrapperXMLStreamWriter((XMLStreamWriter) XMLOutputFactory.newInstance().createXMLStreamWriter(xml, "UTF-8"));

    marshaller.marshal(foo, writer);
} catch (XMLStreamException | FactoryConfigurationError e) {
    e.printStackTrace();
}

4.- 结果:
<?xml version="1.0" encoding="UTF-8"?>
<foo:Object xsi:schemaLocation="http://foo.com/ http://foo.com/foo.xsd" 
 xmlns:foo="http://foo.com/" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <foo:Some attr1="601"/>
        <foo:Others>
            <bar:Another xsi:schemaLocation="http://lipsum.com/bar 
  http://lipsum.com/bar.xsd" xmlns:bar="http://lipsum.com/bar">
          <bar:SomeOther attr2="01"/>
       </bar:Another>
  </foo:Others>
  </foo:Object>

没有更多的 NS 命名空间,希望这对某人有所帮助。

关于xml - JAXB 和命名空间相关问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47356420/

相关文章:

java - 如何统计元素节点数

xml - 使用 lift 将 xml 转换为 Json 的行为很奇怪

java - 无法启动 Activity ComponentInfo : Error inflating class android. support.design.widget.CoordinatorLayout

asp.net-mvc - @using 默认在 Razor View MVC 5

java - JAXB 覆盖 package-info.java : What should be "namespace"?

java - 无法让简单的 XmlAdapter 工作

c# - 如何在xml中嵌入xml

namespaces - 引用外部 clojurescript 命名空间

arrays - 如何创建命名空间数组?

java - 消除生成的 xjb 文件中的错误