java - 从流中过滤/删除无效的 xml 字符

标签 java xml filter jaxb invalid-characters

首先,我无法更改 xml 的输出,它是由第三方生成的。他们在 xml 中插入无效字符。我得到了 xml 的字节流表示形式的 InputStream。除了将流消耗为 String 并进行处理之外,他们是否是一种更干净的方法来过滤掉有问题的字符?我发现了这个:using a FilterReader但这对我不起作用,因为我有字节流而不是字符流。

就其值(value)而言,这是 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>

最佳答案

为了使用过滤器执行此操作,过滤器需要是 XML 实体感知的,因为(至少在您的示例中,有时可能在实际使用中)坏字符作为实体在 xml 中。

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

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

关于java - 从流中过滤/删除无效的 xml 字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3215506/

相关文章:

java - java反序列化期间的大量int数组

java - 当我在 ViewPort 中绘制 JPanel 时,JScrollPane 不滚动

java - 使用java 8以相反的顺序读取文件

excel - 如何更改此基于 VBA/XSLT 的代码,以便将输出写入单个 XML 文件

Ruby 在一种方法中选择和拒绝

python - 如何获得今天 - PySpark(SQL) 中的 “6 months” 日期

java - Apache 2.4.6 Https 页面缓慢问题

c# - (不?)使用 JavaScriptSerializer 将 xml 文件(未知模式)转换为 c# 中的 json

c# - 如何从模板-c#创建xml

arrays - Dynamodb - 按数组中嵌套的对象属性查询