有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java筛选器/从流中删除无效的xml字符

首先,我不能更改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&#x01;
</foo>

共 (1) 个答案

  1. # 1 楼答案

    为了使用过滤器做到这一点,过滤器需要具有XML实体意识,因为(至少在您的示例中,有时在实际使用中)坏字符作为实体存在于XML中

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

    破坏JAXB的转换将在该过程的后面进行