XML解析简介及Xerces-C++简单使用举例

XML是由World WideWeb联盟(W3C)定义的元语言。它已经成为一种通用的数据交换格式,它的平台无关性,语言无关性,系统无关性,给数据集成与交互带来了极大的方便。XML在不同的语言里解析方式都是一样的,只不过实现的语法不同而已。

XML本身只是以纯文本对数据进行编码的一种格式,要想利用XML,或者说利用XML文件中所编码的数据,必须先将数据从纯文本中解析出来,因此,必须有一个能够识别XML文档中信息的解析器,用来解释XML文档并提取其中的数据。然而,根据数据提取的不同需求,又存在着多种解析方式,不同的解析方式有着各自的优缺点和适用环境。选择合适的XML解析技术能够有效提升应用系统的整体性能。

所有的XML处理都从解析开始,无论是使用XSLT或Java语言,第一步都是要读入XML文件,解码结构和检索信息等等,这就是解析,即把代表XML文档的一个无结构的字符序列转换为满足XML语法的结构化组件的过程。

XML基本的的解析方式主要有两种:SAX(Simple API for XML)和DOM(Document ObjectModel)。

SAX是基于事件流的解析。SAX处理的优点非常类似于流媒体的优点。分析能够立即开始,而不是等待所有的数据被处理。而且,由于应用程序只是在读取数据时检查数据,因此不需要将数据存储在内存中。这对于大型文档来说是个巨大的优点。事实上,应用程序甚至不必解析整个文档,它可以在某个条件得到满足时停止解析。一般来说,SAX还比它的替代者DOM快很多。SAX解析器采用了基于事件的模型,它在解析XML文档的时候可以触发一系列的事件,当发现给定的tag的时候,它可以激活一个回调方法,告诉该方法制定的标签已经找到。SAX对内存的要求通常会比较低,因为它让开发人员来决定所要处理的tag。特别是当开发人员只需要处理文档中所包含的部分数据时,SAX这种扩展能力得到了更好的体现。但用SAX解析器的时候编码工作会比较困难,而且很难同时访问同一个文档中的多处不同数据。优点:(1)、不需要等待所有数据都被处理,分析就能立即开始;(2)、只在读取数据时检查数据,不需要保存在内存中;(3)、可以在某个条件得到满足时停止解析,不必解析整个文档;(4)、效率和性能较高,能解析大于系统内存的文档。缺点:(1)、需要应用程序自己负责TAG的处理逻辑(例如维护父/子关系等),文档越复杂程序就越复杂;(2)、单向导航,无法定位文档层次,很难同时访问同一文档的不同部分数据,不支持XPath。

DOM是用与平台和语言无关的方式表示XML文档的官方W3C标准。DOM是以层次结构组织的节点或信息片段的集合。这个层次结构允许开发人员在树中寻找特定信息。分析该结构通常需要加载整个文档和构造层次结构,然后才能做任何工作。由于它是基于信息层次的,因而DOM被认为是基于树或基于对象的。优点:(1)、允许应用程序对数据和结构做出更改;(2)、访问是双向的,可以在任何时候在树中上下导航,获取和操作任意部分的数据。缺点:通常需要加载整个XML文档来构造层次结构,消耗资源大。

基于C/C++语言的XML解析库包括:

(1)、Expat:http://www.libexpat.org/  ;

(2)、die-xml:https://code.google.com/p/die-xml/

(3)、Xerces-C++:http://xerces.apache.org/xerces-c/index.html

(4)、TinyXml:http://www.grinninglizard.com/tinyxml/

Xerces-C++的编译和使用:

1、  从http://xerces.apache.org/xerces-c/download.cgi#verify下载 xerces-c-3.1.1.zip 源代码,并解压缩;

2、  用vs2010打开xerces-c-3.1.1\projects\Win32\VC10\xerces-all目录下的xerces-all.sln;

3、  分别选择SolutionConfigurations、Solution Platforms中相关项,然后选中Solution ‘xerces-all’,-->单击右键,选择执行Rebuild Solution,会在/Build/Win32/VC10目录下生成相应的动态库和静态库,这里选择Static Debug/xerces-c_static_3D.lib和Static Release/xerces-c_static_3.lib进行测试;

4、在’xerces-all’工作空间的基础上新建一个TestXerces工程,选中此工程,分别在Debug和Release下,工程属性(1)、Configuration Properties -->Character Set:Use Unicode Character Set; (2)、C/C++-->General-->Additional Include Directories: ../../../../../src ,C/C++ -->Prerocessor中加入:

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. _CRT_SECURE_NO_DEPRECATE  
  2. _WINDOWS  
  3. XERCES_STATIC_LIBRARY  
  4. XERCES_BUILDING_LIBRARY  
  5. XERCES_USE_TRANSCODER_WINDOWS  
  6. XERCES_USE_MSGLOADER_INMEMORY  
  7. XERCES_USE_NETACCESSOR_WINSOCK  
  8. XERCES_USE_FILEMGR_WINDOWS  
  9. XERCES_USE_MUTEXMGR_WINDOWS  
  10. XERCES_PATH_DELIMITER_BACKSLASH  
  11. HAVE_STRICMP  
  12. HAVE_STRNICMP  
  13. HAVE_LIMITS_H  
  14. HAVE_SYS_TIMEB_H  
  15. HAVE_FTIME  
  16. HAVE_WCSUPR  
  17. HAVE_WCSLWR  
  18. HAVE_WCSICMP  
  19. HAVE_WCSNICMP  

stdafx.h:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #pragma once  
  2.   
  3. #include "targetver.h"  
  4.   
  5. #include <stdio.h>  
  6.   
  7. #include "xercesc/util/PlatformUtils.hpp"  
  8. #include "xercesc/util/XMLString.hpp"  
  9. #include "xercesc/dom/DOM.hpp"  
  10. #include "xercesc/util/OutOfMemoryException.hpp"  
  11. #include "xercesc/util/TransService.hpp"  
  12. #include "xercesc/parsers/SAXParser.hpp"  
  13. #include "xercesc/sax/HandlerBase.hpp"  
  14. #include "xercesc/framework/XMLFormatter.hpp"  

stdafx.cpp:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #include "stdafx.h"  
  2.   
  3. // TODO: reference any additional headers you need in STDAFX.H  
  4. // and not in this file  
  5. #ifdef _DEBUG  
  6.     #pragma comment(lib, "../../../../../Build/Win32/VC10/Static Debug/xerces-c_static_3D.lib")   
  7. #else  
  8.     #pragma comment(lib, "../../../../../Build/Win32/VC10/Static Release/xerces-c_static_3.lib")   
  9. #endif  

TestXerces.cpp:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #include "stdafx.h"  
  2. #include <iostream>  
  3.   
  4. using namespace std;  
  5.   
  6. XERCES_CPP_NAMESPACE_USE  
  7.   
  8. class XStr  
  9. {  
  10. public :  
  11.     // -----------------------------------------------------------------------  
  12.     //  Constructors and Destructor  
  13.     // -----------------------------------------------------------------------  
  14.     XStr(const charconst toTranscode)  
  15.     {  
  16.         // Call the private transcoding method  
  17.         fUnicodeForm = XMLString::transcode(toTranscode);  
  18.     }  
  19.   
  20.     ~XStr()  
  21.     {  
  22.         XMLString::release(&fUnicodeForm);  
  23.     }  
  24.   
  25.     // -----------------------------------------------------------------------  
  26.     //  Getter methods  
  27.     // -----------------------------------------------------------------------  
  28.     const XMLCh* unicodeForm() const  
  29.     {  
  30.         return fUnicodeForm;  
  31.     }  
  32.   
  33. private :  
  34.     // -----------------------------------------------------------------------  
  35.     //  Private data members  
  36.     //  
  37.     //  fUnicodeForm  
  38.     //      This is the Unicode XMLCh format of the string.  
  39.     // -----------------------------------------------------------------------  
  40.     XMLCh*   fUnicodeForm;  
  41. };  
  42.   
  43. #define X(str) XStr(str).unicodeForm()  
  44.   
  45. /* 
  46. * This sample illustrates how you can create a DOM tree in memory. 
  47. * It then prints the count of elements in the tree. 
  48. */  
  49. int CreateDOMDocument()  
  50. {  
  51.     // Initialize the XML4C2 system.  
  52.     try {  
  53.         XMLPlatformUtils::Initialize();  
  54.     } catch(const XMLException& toCatch) {  
  55.         char *pMsg = XMLString::transcode(toCatch.getMessage());  
  56.         XERCES_STD_QUALIFIER cerr << "Error during Xerces-c Initialization.\n"  
  57.             << "  Exception message:"  
  58.             << pMsg;  
  59.         XMLString::release(&pMsg);  
  60.         return 1;  
  61.     }  
  62.   
  63.     // Watch for special case help request  
  64.     int errorCode = 0;  
  65.   
  66.     /*{ 
  67.     XERCES_STD_QUALIFIER cout << "\nUsage:\n" 
  68.     "    CreateDOMDocument\n\n" 
  69.     "This program creates a new DOM document from scratch in memory.\n" 
  70.     "It then prints the count of elements in the tree.\n" 
  71.     << XERCES_STD_QUALIFIER endl; 
  72.     errorCode = 1; 
  73.     }*/  
  74.     if(errorCode) {  
  75.         XMLPlatformUtils::Terminate();  
  76.         return errorCode;  
  77.     }  
  78.   
  79.     {  
  80.         //  Nest entire test in an inner block.  
  81.         //  The tree we create below is the same that the XercesDOMParser would  
  82.         //  have created, except that no whitespace text nodes would be created.  
  83.   
  84.         // <company>  
  85.         //     <product>Xerces-C</product>  
  86.         //     <category idea='great'>XML Parsing Tools</category>  
  87.         //     <developedBy>Apache Software Foundation</developedBy>  
  88.         // </company>  
  89.         DOMImplementation* impl =  DOMImplementationRegistry::getDOMImplementation(X("Core"));  
  90.   
  91.         if (impl != NULL) {  
  92.             try {  
  93.                 DOMDocument* doc = impl->createDocument(  
  94.                     0,                    // root element namespace URI.  
  95.                     X("company"),         // root element name  
  96.                     0);                   // document type object (DTD).  
  97.   
  98.                 DOMElement* rootElem = doc->getDocumentElement();  
  99.   
  100.                 DOMElement*  prodElem = doc->createElement(X("product"));  
  101.                 rootElem->appendChild(prodElem);  
  102.   
  103.                 DOMText*    prodDataVal = doc->createTextNode(X("Xerces-C"));  
  104.                 prodElem->appendChild(prodDataVal);  
  105.   
  106.                 DOMElement*  catElem = doc->createElement(X("category"));  
  107.                 rootElem->appendChild(catElem);  
  108.   
  109.                 catElem->setAttribute(X("idea"), X("great"));  
  110.   
  111.                 DOMText*    catDataVal = doc->createTextNode(X("XML Parsing Tools"));  
  112.                 catElem->appendChild(catDataVal);  
  113.   
  114.                 DOMElement*  devByElem = doc->createElement(X("developedBy"));  
  115.                 rootElem->appendChild(devByElem);  
  116.   
  117.                 DOMText*    devByDataVal = doc->createTextNode(X("Apache Software Foundation"));  
  118.                 devByElem->appendChild(devByDataVal);  
  119.   
  120.                 //  
  121.                 // Now count the number of elements in the above DOM tree.  
  122.                 //  
  123.                 const XMLSize_t elementCount = doc->getElementsByTagName(X("*"))->getLength();  
  124.                 XERCES_STD_QUALIFIER cout << "The tree just created contains: " << elementCount  
  125.                     << " elements." << XERCES_STD_QUALIFIER endl;  
  126.   
  127.                 doc->release();  
  128.             } catch (const OutOfMemoryException&) {  
  129.                 XERCES_STD_QUALIFIER cerr << "OutOfMemoryException" << XERCES_STD_QUALIFIER endl;  
  130.                 errorCode = 5;  
  131.             } catch (const DOMException& e) {  
  132.                 XERCES_STD_QUALIFIER cerr << "DOMException code is:  " << e.code << XERCES_STD_QUALIFIER endl;  
  133.                 errorCode = 2;  
  134.             } catch (...) {  
  135.                 XERCES_STD_QUALIFIER cerr << "An error occurred creating the document" << XERCES_STD_QUALIFIER endl;  
  136.                 errorCode = 3;  
  137.             }  
  138.         } else{// (inpl != NULL)  
  139.             XERCES_STD_QUALIFIER cerr << "Requested implementation is not supported" << XERCES_STD_QUALIFIER endl;  
  140.             errorCode = 4;  
  141.         }  
  142.     }  
  143.   
  144.     XMLPlatformUtils::Terminate();  
  145.     return errorCode;  
  146. }  
  147.   
  148.   
  149. // ---------------------------------------------------------------------------  
  150. //  This is a simple class that lets us do easy (though not terribly efficient)  
  151. //  transcoding of XMLCh data to local code page for display.  
  152. // ---------------------------------------------------------------------------  
  153. class StrX  
  154. {  
  155. public :  
  156.     // -----------------------------------------------------------------------  
  157.     //  Constructors and Destructor  
  158.     // -----------------------------------------------------------------------  
  159.     StrX(const XMLCh* const toTranscode)  
  160.     {  
  161.         // Call the private transcoding method  
  162.         fLocalForm = XMLString::transcode(toTranscode);  
  163.     }  
  164.   
  165.     ~StrX()  
  166.     {  
  167.         XMLString::release(&fLocalForm);  
  168.     }  
  169.   
  170.     // -----------------------------------------------------------------------  
  171.     //  Getter methods  
  172.     // -----------------------------------------------------------------------  
  173.     const char* localForm() const  
  174.     {  
  175.         return fLocalForm;  
  176.     }  
  177.   
  178. private :  
  179.     // -----------------------------------------------------------------------  
  180.     //  Private data members  
  181.     //  
  182.     //  fLocalForm  
  183.     //      This is the local code page form of the string.  
  184.     // -----------------------------------------------------------------------  
  185.     char*   fLocalForm;  
  186. };  
  187.   
  188. inline XERCES_STD_QUALIFIER ostream& operator<<(XERCES_STD_QUALIFIER ostream& target, const StrX& toDump)  
  189. {  
  190.     target << toDump.localForm();  
  191.     return target;  
  192. }  
  193.   
  194. int SAXPrint()  
  195. {  
  196.     // ---------------------------------------------------------------------------  
  197.     //  Local data  
  198.     //  
  199.     //  doNamespaces  
  200.     //      Indicates whether namespace processing should be enabled or not.  
  201.     //      Defaults to disabled.  
  202.     //  
  203.     //  doSchema  
  204.     //      Indicates whether schema processing should be enabled or not.  
  205.     //      Defaults to disabled.  
  206.     //  
  207.     //  schemaFullChecking  
  208.     //      Indicates whether full schema constraint checking should be enabled or not.  
  209.     //      Defaults to disabled.  
  210.     //  
  211.     //  encodingName  
  212.     //      The encoding we are to output in. If not set on the command line,  
  213.     //      then it is defaulted to LATIN1.  
  214.     //  
  215.     //  xmlFile  
  216.     //      The path to the file to parser. Set via command line.  
  217.     //  
  218.     //  valScheme  
  219.     //      Indicates what validation scheme to use. It defaults to 'auto', but  
  220.     //      can be set via the -v= command.  
  221.     // ---------------------------------------------------------------------------  
  222.     static bool                     doNamespaces        = false;  
  223.     static bool                     doSchema            = false;  
  224.     static bool                     schemaFullChecking  = false;  
  225.     static const char*              encodingName    = "LATIN1";  
  226.     static XMLFormatter::UnRepFlags unRepFlags      = XMLFormatter::UnRep_CharRef;  
  227.     static char*                    xmlFile         = 0;  
  228.     static SAXParser::ValSchemes    valScheme       = SAXParser::Val_Auto;  
  229.   
  230.     // Initialize the XML4C2 system  
  231.     try {  
  232.         XMLPlatformUtils::Initialize();  
  233.     } catch (const XMLException& toCatch) {  
  234.         XERCES_STD_QUALIFIER cerr << "Error during initialization! :\n"  
  235.             << StrX(toCatch.getMessage()) << XERCES_STD_QUALIFIER endl;  
  236.         return 1;  
  237.     }  
  238.   
  239.     xmlFile = "../../../../../samples/data/personal-schema.xml";  
  240.     int errorCount = 0;  
  241.   
  242.     //  
  243.     //  Create a SAX parser object. Then, according to what we were told on  
  244.     //  the command line, set it to validate or not.  
  245.     //  
  246.     SAXParser* parser = new SAXParser;  
  247.     parser->setValidationScheme(valScheme);  
  248.     parser->setDoNamespaces(doNamespaces);  
  249.     parser->setDoSchema(doSchema);  
  250.     parser->setHandleMultipleImports (true);  
  251.     parser->setValidationSchemaFullChecking(schemaFullChecking);  
  252.   
  253.     //  
  254.     //  Create the handler object and install it as the document and error  
  255.     //  handler for the parser-> Then parse the file and catch any exceptions  
  256.     //  that propogate out  
  257.     //  
  258.     int errorCode = 0;  
  259.     try {  
  260.         //SAXPrintHandlers handler(encodingName, unRepFlags);  
  261.         //parser->setDocumentHandler(&handler);  
  262.         //parser->setErrorHandler(&handler);  
  263.         parser->parse(xmlFile);  
  264.         errorCount = parser->getErrorCount();  
  265.     } catch (const OutOfMemoryException&) {  
  266.         XERCES_STD_QUALIFIER cerr << "OutOfMemoryException" << XERCES_STD_QUALIFIER endl;  
  267.         errorCode = 5;  
  268.     } catch (const XMLException& toCatch) {  
  269.         XERCES_STD_QUALIFIER cerr << "\nAn error occurred\n  Error: "  
  270.             << StrX(toCatch.getMessage())  
  271.             << "\n" << XERCES_STD_QUALIFIER endl;  
  272.         errorCode = 4;  
  273.     }  
  274.   
  275.     if(errorCode) {  
  276.         XMLPlatformUtils::Terminate();  
  277.         return errorCode;  
  278.     }  
  279.   
  280.     //  
  281.     //  Delete the parser itself.  Must be done prior to calling Terminate, below.  
  282.     //  
  283.     delete parser;  
  284.   
  285.     // And call the termination method  
  286.     XMLPlatformUtils::Terminate();  
  287.   
  288.     if (errorCount > 0)  
  289.         return 4;  
  290.     else  
  291.         return 0;  
  292.   
  293.     return 0;  
  294. }  
  295.   
  296. int main(int argc, char* argv[])  
  297. {  
  298.     CreateDOMDocument();  
  299.   
  300.     SAXPrint();  
  301.   
  302.     cout<<"ok!"<<endl;  
  303.   
  304.     return 0;  
  305. }  

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值