我有一个XML解析器,它会在不完整的XML数据上崩溃。因此,提供给它的XML数据可能是以下之一:
<one><two>twocontent</two</one>
<a/><b/> ( the parser treats it as two root elements )
也处理元素属性(虽然未在上面显示)。
现在,问题是当我从套接字I中读取数据时,我会在片段中获取数据。例如:
<one>one
content</two>
</one>
因此,在将XML发送到解析器之前,我必须构造一个有效的XML并发送它。 什么编程构造(如迭代,递归等)最适合这种情况。
我用C ++编程。
请帮忙。
答案 0 :(得分:7)
简短回答:你做错了。
您的问题混淆了两个不同的问题:
解析格式不正确的XML ,即所谓的标签汤。
示例:由不懂XML或编码糟糕的程序员生成的文件。
说:格式不正确的XML文件根本不是XML文档,这是不公平的。每个正确的XML解析器都会拒绝它。理想情况下,您将努力纠正此数据的来源,并确保生成正确的XML。
或者,使用标签汤解析器,即执行错误纠正的解析器。
有用的标签汤解析器通常实际上是HTML解析器。另一个答案已经指出tidy。
确保您了解此类解析器实际执行的更正步骤,因为没有可以修复XML的通用方法。特别是整洁,“修复”数据非常积极,比真正的浏览器和HTML 5规范更具侵略性。
从套接字解析XML,其中数据在流中逐块地到达。在这种情况下,XML文档可能被视为“无限”,在看到根元素的最终结束标记之前很久就会将其作为显示处理。
示例:XMPP是一个像这样工作的协议。
解决方案是使用基于pull的解析器,例如libxml2中的XMLTextReader API。
如果需要XML子元素的基于树的数据结构作为解析器,则可以为正在读取的每个此类元素构建树结构,而不是为整个文档构建树结构。
< / LI>答案 1 :(得分:2)
什么从套接字连接的另一端向您提供XML?正如你所说,只是因为你从套接字中接收它,你应该丢失的东西是没有意义的。
如果套接字使用TCP(或具有类似属性的自定义协议),则不应缺少XML的部分内容。因此,您应该能够将其全部缓冲,直到另一端发出“文档结束”的信号,然后将其提供给您挑剔的XML解析器。
如果您正在使用UDP或其他“有损”协议,则需要重新考虑,因为显然无法通过随机丢弃片段的频道正确传输大型XML文档。
答案 2 :(得分:1)
因为XML结构是一个层次结构(树),递归将是解决此问题的最佳方法。 您可以在每个子进程上调用递归并修复缺少的XML标识符。 基本上,你将做DOM对象解析器会做同样的事情,只有你将解析文件以修复它的结构。 但有一件事,在我看来,在这种方法中,你将重新编写XML解析器。这不是时间的腰部吗? 也许最好找到一种方法让XML到达正确的结构,而不是试图修复它。
答案 3 :(得分:0)
有多位作家吗?为什么您的解析器不能验证XML?
使用树,其中每个节点代表一个元素并带有一个脏位。第一次出现的节点将其标记为脏,即您期望结束标记,除非该节点的格式为<a/>
。此外,您遇到的第一个元素是根。
当您点击脏节点时,继续推送堆栈中的节点,直到您弹出内容时点击结束标记。
答案 4 :(得分:0)
在您的示例中,一旦检测到丢失,您将如何准确确定内容在开始<two>
标记中的确切位置?正如他们所说,这是非平凡的。