1

我有一个带有两个 xml 的 InputStream 或 String,如下所示:

<?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. 搜索并删除这两<?xml version="1.0 standalone="yes"?>行并将其余行括起来<ROOT> </ROOT>以生成一个有效的 xml,并找出如何从那里解析它

然而,这两种方法似乎都很笨拙且效率低下。有没有更好的办法?

4

2 回答 2

1

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

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

另一方面,如果我希望处理相当长的数据,或者如果响应实体可能包含不确定数量的连接 XML 文档,那么我会考虑InputStream使用自定义包装获得的数据,InputStream或者Reader执行 (a) 剥离声明和 (b) 插入新的根元素。SO上还有其他人问了一个与您在这里面临的问题非常相似的问题,只是他没有要处理的声明。查看 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 数据,并且您希望在单个响应中处理大量数据,那么我认为您需要采用这种方向。

于 2012-09-18T21:47:35.617 回答
1

这是一个糟糕的设计,因为字符串"<?xml"可能会合法地出现在 CDATA 部分或注释中。但是你只需要冒险,在你看到的任何地方拆分文件"<?xml",希望最好,如果它做错了,责怪提出这个想法的人。唯一的选择是为这种 XML 变体编写自己的解析器,这不会很有趣。

于 2012-09-18T21:15:22.330 回答