2

首先,我无法更改 xml 的输出,它是由第三方生成的。他们在 xml 中插入无效字符。我得到了 xml 的字节流表示形式的 InputStream。除了将流转化为字符串并对其进行处理之外,它们是一种更清洁的过滤违规字符的方法吗?我发现了这一点:使用 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&#x01;
</foo>
4

1 回答 1

1

为了使用过滤器执行此操作,过滤器需要能够识别 XML 实体,因为(至少在您的示例中并且可能有时在实际使用中)坏字符作为实体存在于 xml 中。

过滤器将您的实体视为 6 个完全可接受的字符序列,因此不会剥离它们。

破坏 JAXB 的转换发生在该过程的后期。

于 2010-07-09T23:26:08.967 回答