XML解析问题

时间:2009-02-19 08:12:12

标签: c++ xml

我有一个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 ++编程。

请帮忙。

5 个答案:

答案 0 :(得分:7)

简短回答:你做错了。

您的问题混淆了两个不同的问题:

  1. 解析格式不正确的XML ,即所谓的标签汤。

    示例:由不懂XML或编码糟糕的程序员生成的文件。

    • 说:格式不正确的XML文件根本不是XML文档,这是不公平的。每个正确的XML解析器都会拒绝它。理想情况下,您将努力纠正此数据的来源,并确保生成正确的XML。

    • 或者,使用标签汤解析器,即执行错误纠正的解析器。

      有用的标签汤解析器通常实际上是HTML解析器。另一个答案已经指出tidy

      确保您了解此类解析器实际执行的更正步骤,因为没有可以修复XML的通用方法。特别是整洁,“修复”数据非常积极,比真正的浏览器和HTML 5规范更具侵略性。

  2. 从套接字解析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>标记中的确切位置?正如他们所说,这是非平凡的。