2010-07-09 63 views
2

首先,我無法更改xml的輸出,它由第三方生成。他們在XML中插入無效字符。我得到了xml的字節流表示的InputStream。除了將字符串消費到字符串並處理它之外,他們是否更清楚地篩選出違規字符?我發現這個:using a FilterReader但這並不適用於我,因爲我有一個字節流,而不是一個字符流。過濾/從流中刪除無效的xml字符

爲什麼它值得這是一個jaxb解組過程的所有部分,以防萬一提供選項。

如果字符不好,我們不願意拋棄整個流。我們決定刪除它們並繼續。

這是我試圖構建的FilterReader。

public class InvalidXMLCharacterFilterReader extends FilterReader 
{ 

private static final Log LOG = LogFactory 
.getLog(InvalidXMLCharacterFilterReader.class); 

public InvalidXMLCharacterFilterReader(Reader in) 
{ 
    super(in); 
} 

public int read() throws IOException { 
    char[] buf = new char[1]; 
    int result = read(buf, 0, 1); 
    if (result == -1) 
     return -1; 
    else 
     return (int) buf[0]; 
} 

public int read(char[] buf, int from, int len) throws IOException { 
    int count = 0; 
    while (count == 0) { 
     count = in.read(buf, from, len); 
     if (count == -1) 
      return -1; 

     int last = from; 
     for (int i = from; i < from + count; i++) { 
      LOG.debug("" + (char)buf[i]); 
      if(!isBadXMLChar(buf[i])) 
      { 
       buf[last++] = buf[i]; 
      } 
     } 

     count = last - from; 
    } 
    return count; 
} 

private boolean isBadXMLChar(char c) 
{ 
    if ((c == 0x9) || 
     (c == 0xA) || 
     (c == 0xD) || 
     ((c >= 0x20) && (c <= 0xD7FF)) || 
     ((c >= 0xE000) && (c <= 0xFFFD)) || 
     ((c >= 0x10000) && (c <= 0x10FFFF))) 
    { 
     return false; 
    } 
    return true; 
} 

}

這裏是怎麼了解編的:

jaxbContext = JAXBContext.newInstance(MyObj.class); 
Unmarshaller unMarshaller = jaxbContext.createUnmarshaller(); 
Reader r = new InvalidXMLCharacterFilterReader(new BufferedReader(new InputStreamReader(is, "UTF-8"))); 
MyObj obj = (MyObj) unMarshaller.unmarshal(r); 

和一些示例壞的XML

<?xml version="1.0" encoding="UTF-8" ?> 
<foo> 
    bar&#x01; 
</foo> 
+2

你確定*他們*插入無效字符嗎?是不是你正在使用錯誤的編碼讀取二進制流中的字符和/或使用錯誤的編碼顯示讀取的字符? – BalusC 2010-07-09 18:58:01

+0

你應該檢查BalusC的評論。如果您仍然想繼續使用FilteredReader實現,那麼在將字節流轉換爲閱讀器(使用InputStreamReader)的情況下,只要知道字節流的文本編碼就沒有問題。 – 2010-07-09 19:23:54

+0

我不知道BalusC在做什麼。他們是公然無效的XML 1.0字符。我嘗試使用InputStreamReader(以及將其包裝在緩衝讀取器中),但沒有運氣。我會用代碼更新我的問題。 – DanInDC 2010-07-09 20:43:00

回答

1

爲了過濾,以做到這一點,過濾器需要能夠識別XML實體,因爲壞字符(至少在你的例子中,有時可能在實際使用中) xml作爲實體。

該過濾器將您的實體視爲6個完美可接受的字符序列,因此不會剝離它們。

打破JAXB的轉換過程稍後會發生。

+0

沒錯。所以有關於實體感知過濾器的任何想法?或者,我是唯一的選擇,只是將它吸入緩衝區,並使用.replaceAll()這個廢話呢? – DanInDC 2010-07-12 13:44:44

+0

我確定我已經看過一個FilterReader代碼的例子,可以通過正則表達式進行過濾。目前不能把它放在手上,但谷歌可能會找到一些東西。 它基本上等於「將它吸入緩衝區並將.replaceAll()放在它的外面」,但在過濾器代碼中。 – 2010-07-12 14:23:36