从流输入中解析没有根元素的 XML 片段列表
Posted
技术标签:
【中文标题】从流输入中解析没有根元素的 XML 片段列表【英文标题】:Parse a list of XML fragments with no root element from a stream input 【发布时间】:2012-06-28 22:00:18 【问题描述】:在 Java 中使用 SAX api 是否可行?
我尝试解析这样的 XML,但得到了一个
org.xml.sax.SAXParseException: The markup in the document following the root element must be well-formed.
甚至在 endDocument 事件被触发之前。
我不想接受明显但笨拙的解决方案,例如“预先附加自定义根元素或使用缓冲片段解析”。
我正在使用 Java 1.6 的标准 SAX API。 SAX 工厂有 setValidating(false) 以防万一。
【问题讨论】:
***.com/questions/3232110/… 的副本。 可以参考Resolving "The markup in the document following the root element must be well-formed" Exception 【参考方案1】:首先,也是最重要的一点,您正在解析的内容不是 XML 文档。 来自XML Specification:
[定义:只有一个元素,称为根,或文档元素,其任何部分都不会出现在任何其他元素的内容中。]
现在,关于用 SAX 解析这个 - 尽管你说的是笨拙 - 我建议采用以下方法:
Enumeration<InputStream> streams = Collections.enumeration(
Arrays.asList(new InputStream[]
new ByteArrayInputStream("<root>".getBytes()),
yourXmlLikeStream,
new ByteArrayInputStream("</root>".getBytes()),
));
SequenceInputStream seqStream = new SequenceInputStream(streams);
// Now pass the `seqStream` into the SAX parser.
使用SequenceInputStream
是一种将多个输入流连接成单个流的便捷方式。它们将按照传递给构造函数的顺序被读取(或者在这种情况下 - 由Enumeration
返回)。
将它传递给您的 SAX 解析器,您就完成了。
【讨论】:
同意 - 笨拙地附加根元素的原因是因为您正在处理笨拙的数据。否则,一旦您关闭了您打开的第一个元素,SAX 解析器就会相信它已经完成,就像它已经完成一样。对于格式化的 XML 数据流,我也这样做 虽然你提供了一个我已经想到的答案,但实现比我想象的要优雅得多!谢谢你的回答。 嗯,SequenceInputStream
是那些早已被遗忘的实用程序之一,尽管自 Java 1.0 以来就已经存在,但似乎没人知道。只是想提醒它还在那里。 :)以上是关于从流输入中解析没有根元素的 XML 片段列表的主要内容,如果未能解决你的问题,请参考以下文章
无法使用 Jackson XML 直接在根元素内反序列化列表