2013-02-07 90 views
0

我花了一些時間來調查是什麼問題,但我無法解決它。當我在XML下展開並編組時,我會看到不同的XML。JAXB marshlling不會忽略命名空間

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<root> 
<one>test</one> 
<three>\MySG\test.jsp</three> 
<two> 
    <st> 
     <seeta> 
      <Source> 

       <problemtag xmlns="uuid:B89290D2-36FB-4EBC-A581-69B16D59EB92"> 
        <p>deploy_test_page_renderingMetadata</p> 
       </problemtag> 
      </Source> 
     </seeta> 
     <Template id="tcm:1-63-32" title="Smart Compound Component Template"/> 
     <Publication id="tcm:0-1-1" title="Publication"/> 
    </st> 
</two> 
</root> 
  • 在上述XML只有一個標籤(第一個)預期剩餘的所有(包括命名空間)是出乎意料的元素。另一個應用程序發送上述XML。

我的映射都是這樣

package com.seeta.xml; 

import java.util.ArrayList; 
import java.util.List; 

import javax.xml.bind.annotation.XmlAccessType; 
import javax.xml.bind.annotation.XmlAccessorType; 
import javax.xml.bind.annotation.XmlAnyElement; 
import javax.xml.bind.annotation.XmlElement; 
import javax.xml.bind.annotation.XmlRootElement; 

@XmlRootElement(name="root") 
@XmlAccessorType(XmlAccessType.FIELD) 
public class Root { 
    @XmlElement(name="one") 
    private String one; 

    public String getOne() { 
     return one; 
    } 

    public void setOne(String one) { 
     this.one = one; 
    } 

    @XmlElement(name="three") 
    private String three; 

    @XmlAnyElement 
    private List<Object> remaining = new ArrayList<Object>(); 


    public String getThree() { 
     return three; 
    } 

    public void setThree(String three) { 
     this.three = three; 
    } 

    public List<Object> getRemaining() { 
     return remaining; 
    } 

    public void setRemaining(List<Object> remaining) { 
     this.remaining = remaining; 
    } 

    public String toString() { 
     return String.format("One [%s]-> Number of remaing elements [%d]-> three [%s]", one, remaining.size(), three); 
    } 
} 

這裏是我的簡單的代碼

package com.seeta.xml; 

import java.io.ByteArrayInputStream; 
import java.io.ByteArrayOutputStream; 
import java.io.File; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.StringWriter; 
import java.net.URL; 
import java.net.URLDecoder; 

import javax.xml.bind.JAXBContext; 
import javax.xml.bind.JAXBException; 
import javax.xml.bind.Marshaller; 
import javax.xml.bind.Unmarshaller; 
import javax.xml.parsers.DocumentBuilder; 
import javax.xml.parsers.DocumentBuilderFactory; 
import javax.xml.parsers.ParserConfigurationException; 
import javax.xml.transform.OutputKeys; 
import javax.xml.transform.Transformer; 
import javax.xml.transform.TransformerException; 
import javax.xml.transform.TransformerFactory; 
import javax.xml.transform.dom.DOMSource; 
import javax.xml.transform.stream.StreamResult; 

import org.w3c.dom.Document; 
import org.xml.sax.InputSource; 
import org.xml.sax.SAXException; 
     public class JaxbSample { 

     public Document getDOMDocument(InputStream inputStream) throws ParserConfigurationException, SAXException, IOException { 
      DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); 
      documentBuilderFactory.setNamespaceAware(true); 
      DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); 
      if (inputStream != null) { 
       return documentBuilder.parse(new InputSource(inputStream)); 
      } else { 
       return documentBuilder.newDocument(); 
      } 
     } 
     public Root unmarshall(Document document) throws JAXBException { 
      JAXBContext context = JAXBContext.newInstance(Root.class); 
      Unmarshaller unmarshaller = context.createUnmarshaller(); 
      Root root = (Root) unmarshaller.unmarshal(document); 
      return root; 
     } 

     public Document marshall(Root root) throws JAXBException, ParserConfigurationException, SAXException, IOException { 
      JAXBContext context = JAXBContext.newInstance(Root.class); 
      Marshaller marshaller = context.createMarshaller(); 
      Document document = getDOMDocument(null); 
      marshaller.marshal(root, document); 
      return document; 
     } 

     private String transform(Document document) throws TransformerException { 
      StringWriter sw = new StringWriter(); 
      TransformerFactory transformerFactory = TransformerFactory.newInstance(); 
      Transformer transformer = transformerFactory.newTransformer(); 
      transformer.setOutputProperty(OutputKeys.INDENT, "yes"); 
      transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); 
      transformer.transform(new DOMSource(document), new StreamResult(sw)); 
      return sw.toString(); 
     } 

     public void testUnmarshallMarshallUsingDocument() throws ParserConfigurationException, SAXException, IOException, JAXBException, TransformerException { 
      InputStream inputStream = this.getClass().getResourceAsStream("jaxb.xml"); 
      Document document = getDOMDocument(inputStream); 
      Root root = unmarshall(document); 
      Document documentAfterMarshal = marshall(root); 
      String output = transform(documentAfterMarshal); 
      System.out.println(output); 
     } 

     public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException, JAXBException, TransformerException { 
      JaxbSample jaxbTest = new JaxbSample(); 
      jaxbTest.testUnmarshallMarshallUsingDocument(); 
     } 
    } 

輸出

<root> 
<one>test</one> 
<three>\MySG\test.jsp</three> 
<two> 
<st> 
<seeta> 
<Source> 
<problemtag:problemtag xmlns="uuid:B89290D2-36FB-4EBC-A581-69B16D59EB92" xmlns:problemtag="uuid:B89290D2-36FB-4EBC-A581-69B16D59EB92"> 
<p>deploy_test_page_renderingMetadata</p> 
       </problemtag:problemtag> 
      </Source> 
     </seeta> 
<Template id="tcm:1-63-32" title="Smart Compound Component Template"/> 
<Publication id="tcm:0-1-1" title="Publication"/> 
    </st> 
</two> 
</root> 

同時,我試過以下

  • 我試過NamespacePrefixMapper。我可以給不同的命名空間,但不能爲空(「」)。我根本不需要任何命名空間。

新NamespacePrefixMapper(){ 公共字符串getPreferredPrefix(字符串的namespaceURI,字符串建議,布爾requirePrefix){ 回報 「」; } };

  • 我們沒有任何XSD(至少我不知道)在我們的項目試圖不合格的事情

  • 我真的不明白的QName事情

+0

你的'問題標籤'有什麼特別之處以及它是如何映射的。你是否願意分享那部分代碼? –

+0

我已經分享了它。請檢查Root POJO。除第一個標籤(即{{one}})外,所有標籤都映射到{{remaining}}。 –

+0

也許這只是我,但我沒有看到任何名爲'problemtag'的屬性(既不是'source'也不是其他幾個屬性)。我也無法找到任何其他屬性映射到名爲'problemtag'的XML元素。 –

回答

0

如果你想要保留未使用的元素並將它們編組回來,我認爲你應該可以這樣做:

@XmlRootElement(name="Root") 
@XmlAccessorType(XmlAccessType.FIELD) 
class Root { 
    @XmlElement(name="One") 
    private String one; 

    @XmlAnyElement 
    private List<Any> otherElements; 
} 

class AnyAdapter extends XmlAdapter<Element,Any> { 
    @Override 
    public Any unmarshal(Element element) throws Exception { 
     return new Any(element); 
    } 

    @Override 
    public Element marshal(Any any) throws Exception { 
     return any.element; 
    } 
} 

@XmlJavaTypeAdapter(AnyAdapter.class) 
class Any { 
    Element element; 

    Any(Element element) { 
     this.element = element; 
    } 
} 
0

我根本不需要任何命名空間。

您無法單獨使用JAXB來完成此操作。 @XmlAnyElement告訴解組器將它無法處理的元素轉儲到列表中。這些元素具有附加的命名空間。當你編組這些元素時,他們將被寫入其命名空間。

一個選項是讓您使用不知名的DOM命名空間解析器解析傳入的XML,然後使用DOM樹解組它。在Unmarshaller JavaDoc中有一個例子(它使用了一個名稱空間感知解析器;它應該是明顯的改變,以使其不需要名稱空間)。

我真的不明白的QName事情

你的意思是你不明白爲什麼輸出是一個合格的名稱,或者它爲什麼選擇了特定的前綴?或者QNames是什麼意思?

這是一個合格的名稱,因爲這是代表元素的最明確的方式。

我不能告訴你爲什麼挑選這個特殊的前綴; JAXP序列化程序選擇諸如「ns1」,「ns2」等短名稱。

+0

,那麼我試過了,但沒有運氣:( –

+0

@SeetaRamayyaVadali-請用你的*代碼作爲可編譯的示例程序顯示*確切和完整的輸入和輸出我覺得很難相信你拿了一個沒有命名空間的DOM,並將它解組成一個名字空間的對象 – parsifal

+0

現在我正在測試它作爲junit測試用例的簡單性。如果我要分享課程意味着我需要分享這麼多的課程,所以我會創建一個,並明天與大家分享 –