2013-03-16 82 views
0

我試圖建立一種可靠且快速的方式將XML轉換爲使用Java的JSON,並且我已經開始使用XStream來執行此任務。但是,當我在下面運行代碼時由於空白(包括換行符)而導致測試失敗,如果我刪除這些字符,則測試會通過。在使用XStream將XML轉換爲JSON時忽略空白

@Test 
    public void testXmlWithWhitespaceBeforeStartElementCanBeConverted() throws Exception { 
     String xml = 
       "<root>\n" + 
       " <foo>bar</foo>\n" + // remove the newlines and white space to make the test pass 
       "</root>"; 
     String expectedJson = "{\"root\": {\n" + 
       " \"foo\": bar\n" + 
       "}}"; 
     String actualJSON = transformXmlToJson(xml); 

     Assert.assertEquals(expectedJson, actualJSON); 
    } 

    private String transformXmlToJson(String xml) throws XmlPullParserException { 
     XmlPullParser parser = XppFactory.createDefaultParser(); 
     HierarchicalStreamReader reader = new XppReader(new StringReader(xml), parser, new NoNameCoder()); 
     StringWriter write = new StringWriter(); 
     JsonWriter jsonWriter = new JsonWriter(write); 
     HierarchicalStreamCopier copier = new HierarchicalStreamCopier(); 
     copier.copy(reader, jsonWriter); 
     jsonWriter.close(); 
     return write.toString(); 
    } 

測試失敗例外:

com.thoughtworks.xstream.io.json.AbstractJsonWriter$IllegalWriterStateException: Cannot turn from state SET_VALUE into state START_OBJECT for property foo 
    at com.thoughtworks.xstream.io.json.AbstractJsonWriter.handleCheckedStateTransition(AbstractJsonWriter.java:265) 
    at com.thoughtworks.xstream.io.json.AbstractJsonWriter.startNode(AbstractJsonWriter.java:227) 
    at com.thoughtworks.xstream.io.json.AbstractJsonWriter.startNode(AbstractJsonWriter.java:232) 
    at com.thoughtworks.xstream.io.copy.HierarchicalStreamCopier.copy(HierarchicalStreamCopier.java:36) 
    at com.thoughtworks.xstream.io.copy.HierarchicalStreamCopier.copy(HierarchicalStreamCopier.java:47) 
    at testConvertXmlToJSON.transformXmlToJson(testConvertXmlToJSON.java:30) 

有沒有辦法來告訴複製過程中忽略忽略的空白。我找不到任何明顯的方法來實現這一行爲,但我認爲它應該在那裏。我知道我可以預先處理XML以刪除空白區域,或者也許只是使用另一個庫。

更新 我可以解決此問題使用HierarchicalStreamReader接口的裝飾以及手工壓制的空白點,這仍然不覺得理想雖然。這看起來像下面的代碼,這將使測試通過。

public class IgnoreWhitespaceHierarchicalStreamReader implements HierarchicalStreamReader { 
     private HierarchicalStreamReader innerHierarchicalStreamReader; 

     public IgnoreWhitespaceHierarchicalStreamReader(HierarchicalStreamReader hierarchicalStreamReader) { 
      this.innerHierarchicalStreamReader = hierarchicalStreamReader; 
     } 

     public String getValue() { 
      String getValue = innerHierarchicalStreamReader.getValue(); 
      System.out.printf("getValue = '%s'\n", getValue); 
      if(innerHierarchicalStreamReader.hasMoreChildren() && getValue.length() >0)   { 
       if(getValue.matches("^\\s+$")) { 
        System.out.printf("*** White space value suppressed\n"); 
        getValue = ""; 
       } 
      } 
      return getValue; 
     } 
     // rest of interface ... 

任何幫助表示讚賞。

回答

0

比較兩個XML作爲String對象不是一個好主意。如果xml相同,但節點的順序不同,你將如何處理大小寫。

例如

<xml><node1>1</node1><node2>2</node2></xml> 

類似於

<xml><node2>2</node2><node1>1</node1></xml> 

但是當你做一個字符串比較它將始終返回false。

改爲使用像XMLUnit這樣的工具。請參考以下鏈接查看更多細節,

Best way to compare 2 XML documents in Java

+0

感謝您的答覆,但我沒有看到我的表演XML的比較。你是指在刪除空白處的decarator內嗎? – Darren 2013-03-28 10:28:30

+0

我的意思是當你調用Assert.assertEquals時。這兩個參數都是String對象,因此將調用String.equals()方法。相反,您將不得不創建XMLObject類來重寫它的equals方法來執行XML比較。 – ABose 2013-04-03 08:06:59

+0

assertEquals正在測試JSON字符串而不是XML字符串。我同意,如果JSON字符串的內容可能不準確,因此測試可能因此失敗(但我沒有那麼遠),我應該測試等價性。測試只是爲了簡潔而顯示,並不是引發異常的原因。 – Darren 2013-04-04 05:18:31