上个星期所做的项目中涉及到xml文件的解析,所以首先需要选择一个合适的xml解析器,我以前用过libxml2,经过评估觉得它对dom和sax支持得不够全。最后选择了xerces-c这个开源的xml解析器。关于xerces-c的历史及具体细节,可以在对其维护的网站上查看。
http://xerces.apache.org
编译安装好后,可以在sample目录下查看示例代码,但是很多API接口描述得并不清晰。故现将代码整理一下,方便以后自己查阅,同时也希望对其它人有些帮助。
我将一直常用的接口封装成了一个类,包括查找结点,取结点值,更新结点值,删除结点。其中包括有从内存块中读取xml格式的内容并解析,还有将dom树中的内容输出为字节流。
XercesParserXml.h
|
#ifndef XERCES_PARSER_XML_H__ #define XERCES_PARSER_XML_H__
#include <string>
class XercesParserXml { public: bool has(const std::string& srcByte, const std::string& node) const; std::string get(const std::string& srcByte, const std::string& node) const; bool set(std::string& srcByte, const std::string& node, const std::string& value); bool del(std::string& srcByte, const std::string& node);
private:
};
#endif
|
XercesParserXml.cpp
|
#include "XercesParserXml.h"
#include <xercesc/parsers/XercesDOMParser.hpp> #include <xercesc/dom/DOM.hpp> #include <xercesc/sax/HandlerBase.hpp> #include <xercesc/util/XMLString.hpp> #include <xercesc/util/PlatformUtils.hpp> #include <xercesc/framework/MemBufInputSource.hpp>
#if defined(XERCES_NEW_IOSTREAMS) #include <iostream> #else #include <iostream.h> #endif #include <vector>
XERCES_CPP_NAMESPACE_USE
DOMNode* getNode(DOMNode* node, const char* nodeName) { //char* ptr = (char *)nodeName; char ptr[4096] = {0}; sprintf(ptr, "%s", nodeName); if (NULL == ptr) return NULL; char* d = "."; char* p = NULL; p = strtok(ptr, d); std::vector<std::string> vec; while (p) { //printf("name: %s\n", p); vec.push_back(p); p = strtok(NULL, d); } DOMNode* child; DOMNode* curNode = node;
for (unsigned int i = 1; i < vec.size(); i++) { //std::cout << vec[i] << std::endl; if (0 == curNode) { return NULL; } for (child = curNode->getFirstChild(); child != 0; child = child->getNextSibling()) { // have no child ??? char *name = XMLString::transcode(child->getNodeName()); if (vec[i] == name) { //printf("vec[%d]: %s\tname: %s\n", i, vec[i].c_str(), name); XMLString::release(&name); curNode = child; break; } XMLString::release(&name); if (child == curNode->getLastChild()) { std::cout << "such node isn't exist" << std::endl; return NULL; } } }
return curNode; }
class XStr { public : // ----------------------------------------------------------------------- // Constructors and Destructor // ----------------------------------------------------------------------- XStr(const char* const toTranscode) { // Call the private transcoding method fUnicodeForm = XMLString::transcode(toTranscode); }
~XStr() { XMLString::release(&fUnicodeForm); }
// ----------------------------------------------------------------------- // Getter methods // ----------------------------------------------------------------------- const XMLCh* unicodeForm() const { return fUnicodeForm; }
private : // ----------------------------------------------------------------------- // Private data members // // fUnicodeForm // This is the Unicode XMLCh format of the string. // ----------------------------------------------------------------------- XMLCh* fUnicodeForm; };
#define X(str) XStr(str).unicodeForm()
bool XercesParserXml::has(const std::string& srcBytes, const std::string& node) const { // init try { XMLPlatformUtils::Initialize(); } catch (const XMLException& toCatch) { char* message = XMLString::transcode(toCatch.getMessage()); std::cout << "Error during initialization! :\n" << message << "\n"; XMLString::release(&message); return false; } // 1. load the right xml bytes from signal tree XercesDOMParser* parser = new XercesDOMParser(); if (NULL == parser) { return false; } parser->setValidationScheme(XercesDOMParser::Val_Always); parser->setDoNamespaces(true); // optional ErrorHandler* errHandler = (ErrorHandler*) new HandlerBase(); parser->setErrorHandler(errHandler); InputSource* pInputSource = new MemBufInputSource((XMLByte *)srcBytes.c_str(), srcBytes.size(), X("GUID")); if (NULL == pInputSource) { delete parser; delete errHandler; return false; } // 2. parser the xml bytes to a DOM tree parser->parse(*pInputSource); DOMDocument* doc = parser->getDocument(); if (NULL == doc) { delete parser; delete errHandler; delete pInputSource; return false; } // 3. find node of parameter in DOM tree DOMElement* rootElem = NULL; rootElem = doc->getDocumentElement(); DOMNode* testNode = NULL; testNode = getNode(rootElem, node.c_str()); // release source delete parser; delete errHandler; delete pInputSource; //doc->release(); if (testNode == NULL) { return false; } else { return true; } }
|
请遵守《互联网电子公告服务管理规定》及中华人民共和国其他各项有关法律法规。
严禁发表危害国家安全、损害国家利益、破坏民族团结、破坏国家宗教政策、破坏社会稳定、侮辱、诽谤、教唆、淫秽等内容的评论 。
用户需对自己在使用本站服务过程中的行为承担法律责任(直接或间接导致的)。
本站管理员有权保留或删除评论内容。
评论内容只代表网友个人观点,与本网站立场无关。 |
|