【发布时间】:2011-03-14 00:44:48
【问题描述】:
首先,我无法更改 xml 的输出,它是由第三方生成的。他们在 xml 中插入无效字符。我得到了 xml 的字节流表示形式的 InputStream。除了将流转化为字符串并对其进行处理之外,它们是一种更清洁的过滤违规字符的方法吗?我发现了这个:using a FilterReader 但这对我不起作用,因为我有一个字节流而不是字符流。
值得一提的是,这都是 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
</foo>
【问题讨论】:
-
您确定 他们 插入了无效字符吗?使用错误编码从二进制流中读取字符和/或使用错误编码显示读取字符的不是您吗?
-
你应该检查 BalusC 的评论。如果您仍想继续使用 FilteredReader 实现,那么只要您知道字节流的文本编码,就可以将字节流转换为阅读器(使用 InputStreamReader)。
-
我不知道 BalusC 的意思。它们是明显无效的 XML 1.0 字符。我尝试使用 InputStreamReader (以及将其包装在缓冲阅读器中)但没有运气。我会用代码更新我的问题。
-
你能给我们一个你得到的无效字符的例子吗?
-
当前的不良行为是什么?您是否知道您的过滤器未能删除坏字符,或者您在解组过程中遇到可能来自其他原因的错误?
标签: java xml filter jaxb invalid-characters