【问题标题】:filter/remove invalid xml characters from stream从流中过滤/删除无效的 xml 字符
【发布时间】: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&#x01;
</foo>

【问题讨论】:

  • 您确定 他们 插入了无效字符吗?使用错误编码从二进制流中读取字符和/或使用错误编码显示读取字符的不是您吗?
  • 你应该检查 BalusC 的评论。如果您仍想继续使用 FilteredReader 实现,那么只要您知道字节流的文本编码,就可以将字节流转换为阅读器(使用 InputStreamReader)。
  • 我不知道 BalusC 的意思。它们是明显无效的 XML 1.0 字符。我尝试使用 InputStreamReader (以及将其包装在缓冲阅读器中)但没有运气。我会用代码更新我的问题。
  • 你能给我们一个你得到的无效字符的例子吗?
  • 当前的不良行为是什么?您是否知道您的过滤器未能删除坏字符,或者您在解组过程中遇到可能来自其他原因的错误?

标签: java xml filter jaxb invalid-characters


【解决方案1】:

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

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

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

【讨论】:

  • 对。那么对实体感知过滤器有什么想法吗?还是我唯一的选择是将其吸入缓冲区并 .replaceAll() 从中取出废话?
  • 我确定我已经在某处看到了通过正则表达式进行过滤的示例 FilterReader 代码。目前我不能动手,但谷歌可能会找到一些东西。它基本上相当于“将其吸入缓冲区并 .replaceAll() 从中取出垃圾”,但在过滤器代码中。
猜你喜欢
  • 1970-01-01
  • 2011-05-12
  • 1970-01-01
  • 2011-05-13
  • 2017-04-08
  • 2015-03-22
  • 1970-01-01
  • 1970-01-01
  • 2019-08-09
相关资源
最近更新 更多