65.9K
CodeProject 正在变化。 阅读更多。
Home

快速而不费力的 XML XPath 解析器

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.06/5 (8投票s)

2007年5月7日

CPOL

2分钟阅读

viewsIcon

44084

downloadIcon

892

一个简单的 XPath 解析器。

引言

以下是一个快速且简易的 C++ XML XPath 表达式解析器。

背景

我一开始在网上寻找一个快速简单的 C++ XPath 解析器。在开始之前,我想说我找到了很多 XML 库,但没有一个完全符合我的需求。你可能会问,是什么让我开始了 XPath 冒险?嗯,一切都始于我目前正在编写一个需要一些外部设置的开发工具。通常,我会将这些应用程序设置放在注册表中,但这次(因为我有点时间),我想尝试使用 XML 来存储我的应用程序设置。一切都很顺利,我已经写好了我的settings.xml文件,现在我想把它读回来并导航我的设置文件。在经过一番互联网搜索后,似乎 XPath 是最简单的方法。

我使用 C++/CLI 快速尝试了一下 .NET 类,发现它们很容易使用,但这次我想让我的应用程序完全是 C++ 原生的,这就是我决定编写这个快速且简易的 XPathParser 类的原因。

如何使用 XPathParser 类

使用 XPathParser 类非常简单。

首先,将源文件(XPathParser.cppXPathParser.h)添加到您希望使用的目录中,然后将这些文件添加到您的 Visual Studio 项目中。在您要使用该类的文件中包含 XPathParser.h

#include "XPathParser.h"

接下来要做的是包含命名空间 XPathNS

using namespace XPathNS;

此时,我们已经准备好开始了。我们只需要实例化一个 XPathParser 的实例,并传入我们将要对其进行 XPath 表达式处理的 XML 文件的名称。

XPthParser xPath( "books.xml" )

如果您已经走到这一步,那么停止编码就太傻了。现在,我们可以尝试一些 XPath 表达式(如下所示)

// drill down and select all author elements
std::vector<XMLNode> nodeList1 = xPath.selectNodes( "//catalog//book//author" );

// select all author elements
std::vector<XMLNode> nodeList2 = xPath.selectNodes( "//author" );     

// select all price elements
std::vector<XMLNode> nodeList3 = xPath.selectNodes( "//price" ); 

// select all books elements
std::vector<XMLNode> nodeList4 = xPath.selectNodes( "//book" );   

// select all attributes named id
std::vector<XMLNode> nodeList5 = xPath.selectNodes( "//@id" ); 

// select the last book element
std::vector<XMLNode> nodeList6 = xPath.selectNodes( "//book[last()]" );   

// select all book elements with id equal to bk103
std::vector<XMLNode> nodeList7 = xPath.selectNodes( "//book[@id='bk103']" );   

// select all book titles with price > 35 quid
std::vector<XMLNode> nodeList8 = 
            xPath.selectNodes( "/catalog/book[price>35.00]/title" ); 

// select the first node matching author
XMLNode node1 = xPath.selectSingleNode( "//author" );

很简单,不是吗!我们是不是忘记了什么?啊,是的……每个 XPath 表达式都会产生一个 XMLNode 列表。一个 XMLNode 由 "XML 名称"、实际的 "XML 值" 和与 XMLNode 关联的 "任何 XML 属性" 组成。作为参考,下面是 XMLNode 类的样子

struct XMLAttribute
{
   std::string value_;
   std::string name_; 
};

struct XMLNode 
{
   std::string xml_;
   std::string value_;
   std::string name_;
   std::vector<XMLAttribute> nodeAttributes_;
};

回到一些示例代码,下面是一个使用 XPathParser 类的完整示例

using namespace XPathNS;

XPathParser xPath( "books.xml" )
std::vector<XMLNode> nodeList = 
     xPath.selectNodes( "/catalog/book[price>35.00]/title" ); 

// now lets output our nodeList

for ( int loopCnt = 0; loopCnt < nodeList.size(); loopCnt++ )
{
        XMLNode node = nodeList[loopCnt];

        std::cout << "name : " << node.name_ << std::endl;
        std::cout << "value: " << node.value_ << std::endl;
        std::cout << "num attributes : " << node.nodeAttributes.size() << std::endl;
 
        for ( int attribCnt = 0; attribCnt < node.nodeAttributes.size(); attribCnt++ )
    {
               XMLAttribute attrib = node.nodeAttributes[attribCnt];

               std::cout << "attribute name : " << attrib.name_ << std::endl;
               std::cout << "attribute value: " << attrib.value_ << std::endl;              
    }
}

关注点

需要注意的是,在现实生活中,XPathParser 类仅仅是 MSXML 6.0 的一个包装器,这就是为什么本文的标题恰如其分地被称为“快速 & 简易”。有关 MSXML 的更多信息,请访问以下网站:http://www.microsoft.com/downloads/details.aspx?familyid=993c0bcf-4009-be21-27e85e1857b1&displaylang=en

我使用的示例 XML 文件来自 MSDN 网站:http://msdn2.microsoft.com/en-us/library/ms762271.aspx

使用 Visual Studio 2005 SP2 编写的示例应用程序。

历史

这里没有历史记录!!

© . All rights reserved.