繁体   English   中英

从输入流中删除垃圾尾随xml

[英]Remove junk trailing xml from an inputstream

我的免费网络主机将分析javascript附加到所有PHP和HTML文件。 很好,除了我想将XML发送到我的Android应用程序之外,这会使我的文件无效。

由于XML在传递给我的SAX ContentHandler之前已进行了完整的分析(并且分解),所以我不能只是捕捉到异常并与充实的对象一起愉快地继续工作。 (我尝试过,然后对此感到毛骨悚然。)

对合理有效的策略有何建议?

我将要创建一个类,该类将接收我的InputStream,仔细阅读直到找到垃圾,然后中断,然后接受我刚刚写的内容,将其转换回InputStream并传递它,就像什么都没有发生。 但是我担心它的效率会非常低下,有一些我不需要处理的错误(例如破坏诸如嵌入式图像之类的二进制值)并且希望是不必要的。

FWIW,这是一个Android项目的一部分,因此我正在使用android.util.Xml类(请参阅源代码 )。 当我跟踪异常时,它带我去了一个本地的 appendChars函数,无论如何它本身都是从私有方法网络中调用的,因此对任何子类进行子类化似乎都是无用的。

这是我的堆栈跟踪中的重要内容:

E/AndroidRuntime(  678): Caused by: org.apache.harmony.xml.ExpatParser$ParseException: At line 3, column 0: junk after document element
E/AndroidRuntime(  678):    at org.apache.harmony.xml.ExpatParser.parseFragment(ExpatParser.java:523)
E/AndroidRuntime(  678):    at org.apache.harmony.xml.ExpatParser.parseDocument(ExpatParser.java:482)
E/AndroidRuntime(  678):    at org.apache.harmony.xml.ExpatReader.parse(ExpatReader.java:320)
E/AndroidRuntime(  678):    at org.apache.harmony.xml.ExpatReader.parse(ExpatReader.java:277)

我想最后我要征询有关InputStream->手动解析为OutputStream->重新创建InputStream->传递解决方案的意见是否像我认为的那样可怕。

免费的虚拟主机有此问题。 我仍然没有找到一种仍然处于免费模式的替代方案。

“我将创建一个类,将使用我的InputStream,仔细阅读它,直到找到垃圾,然后断开,然后接受我刚刚写的内容,将其转换回InputStream,并像没有发生任何事情一样传递给我。 “我担心它的效率会非常低下,有一些我不需要处理的错误(例如破坏诸如嵌入式图像之类的二进制值)并且希望是不必要的。”

可以的 您可以读入StringBuffer,然后使用ByteArrayInputStream或类似的东西(如适用的话,如StreamReader)。

http://developer.android.com/reference/java/io/ByteArrayInputStream.html

不利的一面是您将整个XML文件读入内存,对于大文件,这在内存方面可能是低效的。

另外,您可以继承InputStream的子类并通过流进行过滤。 您可能只需要通过调用super.read()来覆盖3个read()方法,并在到达垃圾端时进行标记,然后根据需要返回EOF。

我将要创建一个类,该类将接收我的InputStream,仔细阅读直到找到垃圾,然后中断,然后接受我刚刚写的内容,将其转换回InputStream并传递它,就像什么都没有发生。 但是我担心它的效率会非常低下,有一些我不需要处理的错误(例如破坏诸如嵌入式图像之类的二进制值)并且希望是不必要的。

您可以使用FilterStream而不需要缓冲区

最好的做法是在XML的末尾添加一个定界符,例如--theXML ends HERE --或在XML中找不到的字符,例如一组16个\\u04\u003c/code>字符 (然后您只需要检查第16个字节)就可以了。 XML的末尾并阅读直到找到它为止

假设\\u04\u003c/code> delim的实现

class WebStream extends FilterInputStream {

    byte[] buff = new byte[1024];
    int offset = 0, length = 0;

    public WebStream(InputStream i) {
        super(i);
    }

    @Override
    public boolean markSupported() {
        return false;
    }

    @Override
    public int read() throws IOException {
        if (offset == length)
            readNextChunk();
        if (length == -1)
            return -1;// eof
        return buff[offset++];
    }

    @Override
    public int read(byte[] b, int off, int len) throws IOException {
        if (offset == length)
            readNextChunk();
        if (length == -1)
            return -1;// eof

        int cop = length - offset;
        if (len < cop)
            cop = len;
        System.arraycopy(buff, offset, b, off, cop);
        offset += cop;
        return cop;
    }

    private void readNextChunk() throws IOException {
        if (offset <= length) {
            System.arraycopy(buff, offset, buff, 0, length - offset);
            length -= offset;
            offset = 0;
        }
        int read = in.read(buff, length, buff.length - length);
        if (read < 0 && length <= 0) {
            length = -1;
            offset = 0;
            return;
        }

        // note that this is assuming ascii compatible
        // anything like utf16 or utf32 will break here
        for (int i = length; i < read + length; i += 16) {
            if (buff[i] == 0x04) {
                while (buff[--i] == 0x04)
                    ;// find beginning of delim block
                length = i;
                read = 0;
            }
        }
    }

}

请注意,这会抛出错误,进行一些错误检查并需要适当的调试

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM