流xml输入到sax解析器,如何打印xml流



我正试图通过套接字连接到一个远程服务器,并且我从套接字得到大xml响应,由'n'字符分隔。

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <data>
       .......
       .......
    </data>
</Response>n   <---- n acts as delimiter 
<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <data>
        ....
        ....
    </data>
</Response>n
..

我正在尝试使用SAX解析器解析这些xml。理想情况下,我想通过搜索'n'来获得对字符串的完整响应,并将此响应提供给解析器。但是由于我的单一响应非常大,当我在字符串中持有如此大的xml时,我得到了outOfMemory异常..所以唯一的选择是将xml流式传输到SAX。

SAXParserFactory spfactory = SAXParserFactory.newInstance();
SAXParser saxParser = spfactory.newSAXParser();
XMLReader xmlReader = saxParser.getXMLReader();
xmlReader.setContentHandler(new MyDefaultHandler(context));
InputSource xmlInputSource  =   new InputSource(new    
                    CloseShieldInputStream(mySocket.getInputStream()));
xmlReader.parse(xmlInputSource);

我使用closeShieldInputStream来防止SAX因为'n'异常关闭我的套接字流。我问了一个关于……的问题。

现在有时我得到解析错误

org.apache.harmony.xml.ExpatParser$ParseException: At line 1, column 8: not well-formed (invalid token)

我搜索了一下,发现这个错误通常出现在实际xml的编码与SAX期望的不一样的时候。我写了一个C程序并打印出xml,我所有的xml都是用UTF-8编码的。

现在我的问题是……

  1. xml解析中出现上述错误是否有其他原因除了编码问题以外
  2. 是否有办法将输入打印(或写入任何文件)到SAX它从套接字流?

在尝试了Hemal Pandya的答案后…

OutputStream log = new BufferedOutputStream(new FileOutputStream("log.txt"));
InputSource xmlInputSource  =   new InputSource(new CloseShieldInputStream(new   
                                    TeeInputStream(mReadStream, log)));
xmlReader.parse(xmlInputSource);

当我挂载SDCard时,创建了一个名为log.txt的新文件,但它是空的..我使用这个对吗?

好吧最后我是怎么做到的…

我用TeeInputStream自己解决了这个问题,感谢Hemal Pandya的建议。

//open a log file in append mode..
OutputStream log = new BufferedOutputStream(new FileOutputStream("log.txt",true));
InputSource xmlInputSource  =   new InputSource(new CloseShieldInputStream(new   
                                        TeeInputStream(mReadStream, log)));
try{
  xmlReader.parse(xmlInputSource);
  //flush content in the log stream to file..this code only executes if parsing completed successfully 
  log.flush();
}catch(SaxException e){
  //we want to get the log even if parsing failed..So we are making sure we get the log in either case..
  log.flush();
}

是否有办法将输入打印(或写入任何文件)到SAX它从套接字流?

Apache Commons有一个TeeInputStream应该是有用的。

OutputStream log = new BufferedOutputStream(new FileOutputtStream("response.xml"));
InputSource xmlInputSource  =   new InputSource(new    
                    CloseShieldInputStream(new TeeInputStream(mySocket.getInputStream(), log)));

我还没有使用过它,你可能想先在一个独立的程序中尝试它来弄清楚close语义,虽然看看文档和你的需求,看起来你想在结束时单独关闭它。

我不熟悉Expat,但是为了完成您的描述,您需要一个SAX解析器,它支持将数据推入解析器,而不是让解析器从源中提取数据。检查Expat是否支持推送模型。如果是这样,那么您可以简单地从套接字中读取数据块,将其推入解析器,解析器将解析它所能解析的任何数据,缓存任何剩余的数据,以便在下一次推入时使用。根据需要重复操作,直到您准备好关闭套接字连接。在此模型中,n分隔符将被视为节点之间的各种空白,因此必须使用SAX事件来检测新的<Response>节点何时打开和关闭。另外,由于在数据中接收到多个<Response>节点,而XML不允许超过1个顶级文档节点,因此在开始将套接字数据推入解析器之前,需要将自定义的开始标记推入解析器。然后,自定义开始标记将成为顶级文档节点,<Response>节点将是它的子节点。

相关内容

  • 没有找到相关文章