如何在一个文件中分解两个连续的xmls? (爪哇/ Android装置)

时间:2012-09-18 16:57:05

标签: java android xml string parsing

我有一个InputStream或String,里面有两个xmls,如下所示:

<?xml version="1.0" standalone="yes"?> 
<items 
    blahblahblah1 
</items>           
<?xml version="1.0" standalone="yes"?> 
<items 
    blahblahblah2 
</items> 

它们具有相同的格式但数据不同。我想解析它们,但由于这不是有效的xml,我需要找到一种方法来拆分它们。

唯一可以想到的是字符串操作:

  1. 通过子串<?xml version="1.0 standalone="yes"?>
  2. 将它们分成两个单独的字符串
  3. 搜索并删除两条<?xml version="1.0 standalone="yes"?>行,并用<ROOT> </ROOT>包围剩余部分以生成一个有效的xml,并弄清楚如何从那里解析
  4. 然而,这两种方法都看似hacky和低效。还有更好的方法吗?

2 个答案:

答案 0 :(得分:1)

这是一个糟糕的设计,因为字符串"<?xml"可以合法地出现在CDATA部分或评论中。但是你只需要冒险尝试,并且在你看到"<?xml"出现的时候拆分文件,希望是最好的,并且如果错误提出了这个想法,那就责怪谁。唯一的选择是为这个XML变体编写自己的解析器,这不会太有趣。

答案 1 :(得分:1)

我在这里提出的任何建议都没有经过测试,但这些是我认为我会采取的路线。

如果预计响应长度很小,我个人可能只是按照您的建议将连接的XML响应放入String,然后使用标准String方法提取单独的XML文档,,如您所建议的那样,删除XML声明字符串并用一对根元素包装整个批次。这取决于您是想用单个文档还是多个文档提供XML解析器。我很久没有处理BasicHttpResponse,但我认为你可以使用InputStream得到mBasicHttpResponse.getEntity().getContent()响应实体,然后使用其中一种方法获得String InputStream 1}}来自InputStream

另一方面,如果我希望处理相当冗长的数据,或者如果响应实体可能包含不确定数量的连接XML文档,那么我会考虑使用自定义{包装获取的InputStream。 {1}}或Reader执行(a)剥离声明和(b)插入新的根元素。除了他没有要处理的声明之外,SO上有其他人就你面临的问题提出了一个非常相似的问题here。查看user656449的答案,我们看到了如何在将InputStream包含一些虚拟根元素之前将其传递给SAX解析器的建议:

(公开复制自引用的SO问题/答案):

SAXParserFactory saxFactory = SAXParserFactory.newInstance();
SAXParser parser = saxFactory.newSAXParser();

parser.parse(
    new SequenceInputStream(
        Collections.enumeration(Arrays.asList(
        new InputStream[] {
            new ByteArrayInputStream("<dummy>".getBytes()),
            new FileInputStream(file),//bogus xml
            new ByteArrayInputStream("</dummy>".getBytes()),
        }))
    ), 
    new DefaultHandler()
);

但另外在这种情况下,您可以用自己创建的某种FileInputStream替换CustomFilterFileInputStream来执行声明行的剥离。您的CustomFilterFileInputStream将围绕从InputStream获得的BasicHttpResponse,然后使用SequenceInputStream添加新的根标记。

如果您真的 以这种方式接受XML数据,并且如果您希望在单个响应中处理大量数据,那么我认为您需要这样做的方向。