在没有其他库的情况下,在标准C / C ++中解析XML

时间:2012-01-14 14:16:24

标签: c++ c xml parsing

我有一个XML(假设它是有效的),我必须解析它并将其存储在树中。

解析它的最佳方法是什么,不使用其他库,只是对字符串进行基本操作?

请记住,我不必验证它,只需将其解析并记忆到树中。

3 个答案:

答案 0 :(得分:7)

XML的基本结构非常简单:

<tagname [attribute[="value"] ...]>content</tagname>

其中内容可能包含普通文本和更多XML结构,或者包含特殊形式

<tagname [attribute[="value"] ...]/>

相当于

<tagname [attribute[="value"] ...]></tagname>

就是这样。空洞的内容。

因此,如果您不需要解释DTD或做其他奇特的事情,您可以执行以下操作:

  1. 检查第一个非空白字符是<。如果没有,您没有XML,只能给出错误并退出。

  2. 现在跟随标记名称,直到第一个空格,或/>字符。存储它。

  3. 如果下一个非空白字符为/,请检查其后跟>。如果是这样,您已经完成解析并可以返回结果。否则,您的XML格式不正确,可能会因错误退出。

  4. 如果字符为>,那么您已找到begin标记的结尾。现在遵循内容。继续步骤6.

  5. 否则以下是一个论点。解析,存储结果,然后在步骤3继续。

  6. 阅读内容,直到找到<字符。

  7. 如果该字符后跟/,那么它就是结束标记。检查它后面是标记名称和>,如果是,则返回结果。否则,抛出错误。

  8. 如果你到了这里,你就找到了嵌套XML的开头。使用此算法解析,然后在6继续。

答案 1 :(得分:6)

阅读XML看起来很简单,但正确地执行它会涉及一些您并不真正想要处理的复杂问题。实际上,编写一个简单的XML解析器实际上相当于创建另一个XML库。我已经完成了它,并且这个版本的不完整版本位于我的磁盘上。即使您不需要验证XML结构:

  • 无论您是否验证,您都需要处理&lt;等实体引用以及各种字符实体引用,例如&#65;&#xa;
  • XML文档的简单主体相对简单,但标题是一个特别难以处理的DTD:有两个版本略有不同,你可能需要处理内联DTD
  • 因为这些令人讨厌的字符数据段
  • ,即使身体也不是完全无关紧要的
  • 即使没有验证,您也可能需要支持外部实体参考
  • 对于XML的各个部分,接受和/或拒绝的字符也有些有趣
  • 请注意,XML是根据Unicode定义的,对此的正确处理也不是完全无关紧要的:只使用charwchar_t只是不切断它。

我实现的第一个版本是一个很好的小迭代器,用于弹出遇到的所有元素。这允许在迭代器用户选择时轻松停止并继续解析的好功能。不幸的是,当我尝试使用各种实体引用进行复制时,我没有得到它。它可以很好地解析简单的XML文件,但是规范中的一些怪癖我只是不对。

对我来说最有效的方法是创建一个简单的递归式解析器,并结合适当的缓冲区堆栈,以稍微透明地处理实体引用。但是,要完全完成这个,我仍然需要处理一些编码问题,最后我只有更高优先级的项目(在我的业余时间,就是这样)。

总结:显然,它可以像其他人那样完成。这可能是一个毫无意义的练习,除非你有一个非常聪明的想法,这使你的实现比其他选择更适合。

答案 2 :(得分:3)

最好的 方法是从头开始重新实现这样的库 而不使用任何其他库......

欢迎您使用现有的库,例如pugixml。它的安装就像将文件添加到项目并开始使用一样简单。与其他验证解析器相比,它是轻量级的,例如Xerces。