2017-11-17 10 views
0

JAXBと名前空間の問題

<?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> 

< FOO:

@XmlAnyElement(lax = true) 
    @XmlElementRefs({ 
     @XmlElementRef(name="Another", type=Another.class, required=false) 
    }) 
    protected List<Object> any; 

それ:JAXBクラスにおけるその他/ >要素は次のように宣言されています独自の名前空間を持つ他の要素の未知数を含むことがあります。

問題:別の要素としてマーシャリングさ別>:

私は<バーを取得するので、私マーシャルSome.classオブジェクト、JAXBは、NS0としてルート要素にAnother.classの名前空間を置きますメソッドの名前空間が含まれています。ルート要素に再度名前空間を必要としません。

これはバー以降の問題です。もう1つは>ではありません。したがって、Some.classオブジェクトを空のリストにマーシャリングすると、常にxmlns:ns0を持つことになります。

私はjsonからXMLに変換する必要があり、Jacksonは "any"リストが持つ可能性のある型を知る必要があるため、@XmlElementRefsおよび@XmlElementRefアノテーションが必要です。すべてのヘルプはapreciatedされるだろう

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. 

は、どのように私はJAXBのOracle/MOXY実装に伝えることができます。

答えて

0

は、念のためにいくつかのいずれかが、私は不要な名前空間を削除する方法を持って、これを必要とする、トリックがてXMLStreamWriter

ステップから提供された1.-てXMLStreamWriterをラップするためにやっWrapperXMLStreamWriterクラスを作成します。

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.-クレート第一歩

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

の所与てXMLStreamWriterと通常

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.-マーシャルFooのインスタンスとしてマーシャラー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 n amespaces、これは誰かを助けることを願っています。

関連する問題