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

来源:互联网 发布:c语言!= 编辑:程序博客网 时间:2024/06/10 14:52

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 plaincopy在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 plaincopy在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 plaincopy在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 plaincopy在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 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 查分网页崩溃怎么办 记事本回车键不能换行怎么办 网页xml 载入失效怎么办 网页没有搜索栏怎么办 咖喱调料打开了怎么办 煮咖喱水放多了怎么办 营业执照4年没用怎么办 刷赞网站打不开怎么办 网页界面变大了怎么办 照片在易企秀放不完整怎么办 易企秀审核未通过怎么办 微信文件过期怎么办 商家一直不退款怎么办 商家不退运费怎么办 电源标签没了怎么办 淘宝退货的邮费怎么办 淘宝店铺未授权怎么办 商家收款不发货怎么办 厂家收款不发货怎么办 微信支付没到账怎么办 二维码被涂了怎么办 手机老是卡顿怎么办 买完东西降价怎么办 买家不补邮费怎么办 win10网络初始化失败怎么办 win10电脑初始化失败怎么办 获取ip地址失败怎么办 oppor11开不了机怎么办 拼多多商家发错货怎么办 刷好评兼职骗怎么办 公司不想经营了怎么办 外地开公司手续怎么办 淘宝周平均值5.8怎么办 店铺宝贝降权怎么办 淘宝链接被屏蔽怎么办 闲鱼宝贝被降权怎么办 淘宝店没有订单怎么办 拼多多被降权了怎么办 oppo手机流量卡怎么办 刷好评兼职被骗怎么办 淘宝客服态度不好怎么办