2009-02-19 175 views
0

我有一个XML解析器,它在不完整的XML数据上崩溃。因此,提供给它的XML数据可能是下列之一:XML解析问题

<one><two>twocontent</two</one> 

<a/><b/> (the parser treats it as two root elements) 

也处理元素属性(虽然上面未显示)。

现在,问题是,当我从套接字读取数据时,我得到了碎片中的数据。例如:

<one>one 

content</two> 

</one> 

因此,发送XML解析器之前,我必须建立一个有效的XML,并将其发送。 什么编程构造(如迭代,递归等)将是最适合这种情况。

我用C++编程。

请帮忙。

+0

解析器崩溃是什么意思?按照规范,XML解析器应该在遇到格式不正确的XML时放弃回家。 – 2009-02-19 08:46:14

+0

你不应该写一个XML解析器。这就像从头开始构建自己的汽车引擎。 :-) – 2009-02-19 08:48:55

回答

0

有没有多个作家?为什么您的解析器不验证XML?

使用树,其中每个节点代表一个元素,并带有一个脏位。节点的第一次出现将其标记为肮脏,即您期待结束标记,除非该节点的形式为<a/>。另外,你遇到的第一个元素是根。

当你点击一个脏节点时,不断推送节点在堆栈中,直到你点击结束标记,当你弹出内容时。

+0

感谢那个dirkgently,它的工作就像一个魅力 – ardsrk 2009-02-20 04:39:37

1

由于XML结构是一个层次结构(树),递归将是解决这个问题的最好方法。 您可以调用每个子项的递归并修复缺少的XML标识符。 基本上,你会做同样的事情的DOM对象解析器会做,只有你会解析文件,以解决它的结构。 但是有一件事情,在我看来,就好像在这种方法中你要重写XML解析器一样。这不是时间的腰? 也许最好找到一种方法让XML到达正确的结构,而不是试图修复它。

0

在你的例子中,一旦你发现它缺失,你将如何确定内容中的哪个位置将开放<two>标记?正如他们所说,这是不平凡的。

2

什么是从套接字连接的另一端喂给你的XML?正如你所说的,仅仅因为你从一个套接字接收到它,你没有任何意义。

如果套接字使用TCP(或具有类似属性的自定义协议),则不应缺少XML的某些部分。因此,您应该能够缓冲所有内容,直到另一端发出“文档结束”信号,然后将其提供给您挑剔的XML解析器。

如果您使用的是UDP或其他“有损”协议,则需要重新考虑,因为显然无法通过随机丢弃碎片的通道正确传输大型XML文档。

7

简短回答:你做错了。

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

未在所有格式良好的XML 数据
  1. 解析,即所谓的标记汤。

    示例:由不懂XML的编程人员生成的文件或编码实践不好的文件。

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

    • 或者,使用标记汤分析器,即进行纠错的分析器。

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

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

  2. XML从插座,其中数据到达块逐块在一个流解析。在这种情况下,XML文档可能会被视为“无限”,并且在查看根元素的最终结束标记之前很久就会处理该块。

    例如:XMPP是一个像这样工作的协议。

    • 解决方案是使用基于拉的解析器,例如libxml2中的XMLTextReader API。

    • 如果需要XML子元素为解析器的基于树的数据结构,则可以为每个正在读取的元素构建树结构,而不是整个文档。