📄 xmlwrapper.hpp
字号:
#ifndef XMLWRAPPER_HPP#define XMLWRAPPER_HPP// #include <libxml2.h>#include <libxml2/libxml/tree.h>#include <libxml2/libxml/parser.h>#include <libxml2/libxml/xpath.h>#include <exception>#include <vector>#include <string>#include <iostream>namespace XMLWrapper{ using namespace std; struct DOMException:exception { const char* what() const throw() { return msg.c_str(); } DOMException(const string& errMsg):msg(errMsg){} ~DOMException()throw(){} private: string msg; }; enum NodeType { INVALIDE_NODE = 0, ELEMENT_NODE = 1, ATTRIBUTE_NODE = 2, TEXT_NODE = 3, CDATA_SECTION_NODE = 4, ENTITY_REF_NODE = 5, ENTITY_NODE = 6, PI_NODE = 7, COMMENT_NODE = 8, DOCUMENT_NODE = 9, DOCUMENT_TYPE_NODE = 10, DOCUMENT_FRAG_NODE = 11, NOTATION_NODE = 12, HTML_DOCUMENT_NODE = 13, DTD_NODE = 14, ELEMENT_DECL = 15, ATTRIBUTE_DECL = 16, ENTITY_DECL = 17, NAMESPACE_DECL = 18, XINCLUDE_START = 19, XINCLUDE_END = 20, DOCB_DOCUMENT_NODE = 21 }; ///类型前向声明 struct Document; struct Element; struct Node { Node(void* val):pNode((long)val) {} Node():pNode(0){} virtual ~Node() {} bool isNull() { return 0==pNode; } virtual NodeType type() { return (NodeType)(0==pNode?0:(xmlNodePtr)pNode)->type; } Document getOwnerDocument(); template<typename T> T impl() { return (T)pNode; } operator Document(); operator Element(); string name()const; Node(const Node& src); /*! \fn XMLWrapper::Node::value()const */ string value()const; Node parent()const; /*! \fn XMLWrapper::Node::nextSibling()const */ Node nextSibling()const { /// @todo implement me return Node(((xmlNodePtr)pNode)->next); } Node previousSibling()const; size_t childrenCount(); protected: long pNode; }; struct Document:Node { Document(const char* fileName):isHolder(true) {// pNode=(long)xmlReadFile(fileName,NULL,0); pNode=(long)xmlParseFile(fileName);#ifdef XMLWRAPPER_DEBUG assert(pNode);#endif if(!pNode) { throw DOMException(string("load file failed,file name=")+fileName); } } Document(xmlDocPtr pimpl):Node(pimpl),isHolder(false){} ~Document() {#ifdef XMLWRAPPER_DEBUG assert((xmlDocPtr)pNode->type==DOCUMENT_NODE);#endif if(pNode&&isHolder)xmlFreeDoc((xmlDocPtr)pNode); } Element getRootElement(); string encoding()const; private: const bool isHolder; }; struct Element:Node { Element():Node(NULL){} Element(xmlElementPtr pimpl):Node(pimpl){} Element(const Element& src); string getAttributeValue(const string& attrName); void setAttributeValue(const string& name,const string& value); Element addChildElement(const string& name); }; struct NodeSet { size_t count() { return _container.size(); } Node getAt(size_t index) { if(index<_container.size())return _container[index]; else throw DOMException("invalid index of NodeSet"); } void push_back(const Node& val) { _container.push_back(val); } private: vector<Node> _container; }; struct XPathProcessor { XPathProcessor(Document& pDoc) { pContext=xmlXPathNewContext(pDoc.impl<xmlDocPtr>()); } ~XPathProcessor() { xmlXPathFreeContext(pContext); } Node selectSingleNode(Node& refNode,const char* expr); NodeSet selectNodes(Node& refNode,const char* expr); private: xmlXPathContextPtr pContext; };}//helper classstruct convertor{ iconv_t cd; std::string msg; convertor(const char* from,const char* to) { cd=iconv_open(to,from); } ~convertor() { iconv_close(cd); } std::string convert(const char* in) { struct arrayGuard { char* ptr; arrayGuard(char* p):ptr(p){}; ~arrayGuard(){delete[] ptr;} }; size_t inLen=strlen(in); char* inBuff=new char[inLen+6]; arrayGuard ing(inBuff); bzero(inBuff,inLen+1); strcpy(inBuff,in); size_t outLen=inLen*2+4; char* outBuff=new char[outLen]; char* outPtr=outBuff; arrayGuard outg(outBuff); bzero(outBuff,outLen); size_t ret=iconv(cd,(char**)&inBuff,&inLen,&outPtr,&outLen); return std::string(outBuff); }};#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -