简单的 C++ XML 解析器






3.56/5 (17投票s)
一个仅具有基本功能的简单 C++ XML 解析器
引言
我写这篇文章是因为我需要一个基本的 XML 解析器,并且在互联网上找不到适合我需求的解析器(一个轻量级的解析器)。
现有的解析器的复杂性相当令人望而生畏,需要大量的知识才能理解。如果你不是一个经验丰富的 C++ 程序员,很难弄懂代码,如果你是,那你可能已经写了自己的解析器。
我编写了 parse 函数,然后是一系列用于存储解析数据的类,以及一个关于如何使用它的示例(基于 MFC 对话框和树状视图)。这个解析器非常简单,只有基本的功能,没有花哨的东西。它有一些限制。
- 该解析器在一定程度上识别注释。如果 XML 文件中的任何注释出现在根节点之外,都会生成一个错误。
- 截至 2010 年 9 月 29 日,已添加了一些 CDATA支持。它仍然是有限的(例如//< 
 
Cxml 类是该项目的“主力”,包含 parse 函数
bool Cxml::ParseString(_TCHAR* szXML); 
解析后,需要将信息以易于使用的方式存储在内存中,因此存在 Node 和 Attribute 类。
Node 类具有类似树的结构,包含一个父指针和子节点列表。它还包含一个属性列表。
除了这些类之外,还有一组 Utils 文件(.h & .cpp),其中包含一些实用函数。
如何使用?
好的,要使用它,您需要执行以下操作
- Add#include "Cxml.h" 到您的项目中。 
- 创建一个类的实例Cxml *oxml = new Cxml(); 
- 将包含 XML 代码的 string的指针传递给parse函数oxml->ParseString(szXML); 
在 ParseString 返回后,XML 的结构将复制到类中,并且可以通过...来检索 XML 根节点。
oxml->GetRootNode(); 
...调用。
这里有一个特点。因为我采用了“后进先出”的方式,所以节点将以与它们在原始 XML 字符串中出现的顺序相反的顺序组织。
可以使用 Node 对象的 public 函数进行导航。但请记住,GetNextChild() 函数会增加计数器的位置,而我没有实现重置它的方法。
理解内部工作原理的最佳方法是获取演示项目并自行测试。您需要 Visual Studio 2008 来编译现有项目,而无需重建。如果您重建,请记住:它尚未经过 Unicode 测试。
下载项目并解压。编译。运行它并按加载按钮。
 
 
选择提供的 XML 文件之一。点击打开。
 
 
这是提供的其中一个 XML 文件得到的结果。
<CATALOG>
...
    <PLANT>
        <COMMON>Snakeroot</COMMON>
        <BOTANICAL>Cimicifuga</BOTANICAL>
        <ZONE>Annual</ZONE>
        <LIGHT>Shade</LIGHT>
        <PRICE>$5.63</PRICE>
        <AVAILABILITY>071199</AVAILABILITY>
    </PLANT>
    <PLANT>
        <COMMON>Cardinal Flower</COMMON>
        <BOTANICAL>Lobelia cardinalis</BOTANICAL>
        <ZONE>2</ZONE>
        <LIGHT>Shade</LIGHT>
        <PRICE>$3.02</PRICE>
        <AVAILABILITY>022299</AVAILABILITY>
    </PLANT>
</CATALOG>
历史
- 2010 年 9 月 20 日
- Added
- 2010 年 9 月 21 日
- 修订
- 2010 年 9 月 22 日
- 新版本项目已更新
- 修正了多个属性的错误
- 添加了“一些”注释支持。根节点外的注释将产生错误
- 2010 年 9 月 28 日
- 经过 Unicode 测试,并为测试添加了 Unicode XML
- 从项目中删除了智能感知文件
- 修正了 Lorenzo Gatti 发现的混淆单引号和双引号与实际分隔符的错误
- 2010 年 9 月 29 日
- 添加了对 UNICODE 字符集的运行时支持!程序必须使用此字符集编译
- 2010 年 9 月 29 日
- 已添加对 CDATA节的一些支持
- 我还发现 Parse 函数需要一些重构,因为它变得庞大且难以理解。
- 2010 年 10 月 1 日
- 用动态分配的替换了项目中的所有固定大小的 char数组。
- 添加了对处理指令的支持。所有处理指令现在都被视为一种特殊类型的节点,就像注释一样。
- 注释现在也可以存在于 XML 的根节点之外,因为现在最低级别的节点是 XML_DOC节点,而不是 XML 的根节点。
 
 


