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

And*_*rei 2 c c++ xml parsing

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

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

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

cel*_*chk 7

XML的基本结构非常简单:

<tagname [attribute[="value"] ...]>content</tagname>
Run Code Online (Sandbox Code Playgroud)

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

<tagname [attribute[="value"] ...]/>
Run Code Online (Sandbox Code Playgroud)

这相当于

<tagname [attribute[="value"] ...]></tagname>
Run Code Online (Sandbox Code Playgroud)

那是,.空的内容.

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

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

  2. 现在遵循的标签名,直到第一个空格,或者/>字符.存储它.

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

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

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

  6. 阅读内容,直到找到一个<角色.

  7. 如果该字符后跟/,则它是结束标记.检查它后面跟着标签名称>,如果是,则返回结果.否则,抛出一个错误.

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

  • (另外,鉴于至少有一个PI非常普遍,你的"解析器"可能会在大多数真实的XML上立即失败.) (2认同)

Die*_*ühl 6

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

  • 你是否验证或没有,你需要处理像实体引用&lt;和各种类似字符实体引用&#65;&#xa;
  • XML文档的简单主体相对简单,但标题是一个特别是DTD处理的主要问题:有两个版本略有不同,您可能需要处理内联DTD
  • 由于这些恼人的角色数据段,甚至身体也不是完全无足轻重的
  • 即使没有验证,您可能需要支持外部实体引用
  • 对于XML的各个部分要接受和/或拒绝的字符也有些有趣
  • 请注意,XML是根据Unicode定义的,对此的正确处理也不是完全无关紧要的:只是使用char或者wchar_t只是不删除它.

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

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

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