⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmlnode.h

📁 可移植的xml库。已经在windows和linux上测试通过。只使用C++ Runtine
💻 H
字号:
#ifndef LIBXML_XMLNODE_H
#define LIBXML_XMLNODE_H

//xmlnode.h

enum XMLNODETYPE
{
	XNT_TAG,
	XNT_CDATA,
	XNT_META,
	XNT_COMMENT,
};

enum XMLNODEFLAGS
{
	XNF_OPEN_TAG,
	XNF_CLOSE_TAG=1,
	XNF_INDEP_TAG=2,
	XNF_FULL_NODE=4,
};

//大于等于此上限的文件只能用CXMLParser载入
#ifndef XMLFSLIMITTOLOAD
#define XMLFSLIMITTOLOAD
	enum XMLFSLIMITTOLOAD
	{
		XFSL_MAX=0x8000000,//128M
	};
#endif//XMLFSLIMITTOLOAD

class CXMLNodeCache;

class CXMLNode
{
	char *m_nod;			//name or data
	void *m_dummy;
	unsigned m_bs;			//名称或数据缓冲区的总大小
	unsigned m_len;			//名称或数据的长度
	unsigned m_flags;		//开标签、关标签或者独立标签
	CXMLNode *m_prev;
	CXMLNode *m_next;
	CXMLNode *m_last;		//last child
	CXMLNode *m_first;		//first child
	CXMLAttrib *m_head;		//first attrib
	CXMLAttrib *m_tail;		//last attrib
	CXMLNode *m_parent;
	unsigned m_attribs;		//属性数量
	unsigned m_children;	//子节点数
	CXMLNodeCache *m_xnc;	//node cache
	unsigned short m_type;	//标签或者数据
	unsigned short m_depth;	//处在XML树中的深度
	static unsigned m_indent;//缩进量
	void reset();
	void clean();
	int formatNod(CXMLCodec *xc,CXMLNode*& p,const char*& fmt,va_list& ap);
	int formatAttrib(CXMLNode*& p,const char*& fmt,va_list& ap);
public:
	CXMLNode();
	CXMLNode(const CXMLNode& x);
	CXMLNode(CXMLCodec *xc,const char *nod,...);
	CXMLNode(CXMLCodec *xc,const char *nod,va_list ap);
	CXMLNode(const char *nod,CXMLAttrib& a);//especially for meta node
	CXMLNode(CXMLCodec *xc,const char *nod,unsigned flags=0);
	CXMLNode(CXMLCodec *xc,const char *nod,const char *fmt,...);//refer to build(nod,fmt,ap)
	CXMLNode(CXMLCodec *xc,const char *nod,const char *fmt,va_list ap);	//as above

	~CXMLNode();

	void free();

	operator char*() const;
	operator const char*() const;
	CXMLNode& operator=(const char *nod);
	CXMLNode& operator=(const CXMLNode& x);

	bool operator==(const char *nod);
	bool operator!=(const char *nod);
	bool operator==(const CXMLNode& x);
	bool operator!=(const CXMLNode& x);
	
	bool isRoot() const;
	bool isLast() const;
	bool isFirst() const;
	bool isNoChild() const;
	bool isTypeOf(unsigned type) const;
	bool isNodOf(const char *nod,unsigned len=0) const;
	bool isDepthOf(unsigned depth) const;
	bool isOpenOf(const char *nod,unsigned len=0) const;
	bool isUnder(const CXMLNode& x) const;
	bool isAbove(const CXMLNode& x) const;
	bool isSameTo(const CXMLNode& x) const;
	bool isChildOf(const CXMLNode& x) const;
	bool isParentOf(const CXMLNode& x) const;
	bool isNodOfExact(const char *nod,unsigned len=0) const;
	bool isSameToExact(const CXMLNode& x) const;
	bool isAttribExist(const char *name,unsigned len=0,bool exact=false) const;
	bool isTypeOf(const char *nod,unsigned len,unsigned type,bool exact=false) const;
	bool isChildExist(const char *nod,unsigned len=0,unsigned type=0,unsigned depth=1,bool exact=false) const;

	void* getDummy() const;
	unsigned getLen() const;
	unsigned getType() const;
	unsigned getDepth() const;
	CXMLNode* getPrev() const;
	CXMLNode* getNext() const;
	const char* getNod() const;
	unsigned getBufSize() const;
	CXMLNode* getParent() const;
	unsigned getAttribs() const;
	unsigned getChildren() const;
	CXMLNode* getLastChild() const;
	CXMLNode* getFirstChild() const;
	CXMLNodeCache* getCache() const;
	CXMLAttrib* getLastAttrib() const;
	CXMLAttrib* getFirstAttrib() const;
	unsigned getFlags(unsigned mask=0xffffffff) const;

	CXMLNode* getRoot() const;
	unsigned getIndex() const;
	unsigned getSiblings() const;
	CXMLNode* getLastSibling() const;
	CXMLNode* getFirstSibling() const;
	CXMLNode* getChildAt(unsigned idx) const;
	CXMLNode* getSiblingAt(unsigned idx) const;
	CXMLAttrib* getAttribAt(unsigned idx) const;

	unsigned strBytes() const;
	unsigned blockBytes() const;

	static unsigned getIndent();

	void resetFlags();
	void setDummy(void *p);
	void setType(unsigned type);
	int clone(const CXMLNode& x);
	void setFlags(unsigned mask);
	void setDepth(unsigned depth);
	void clearFlags(unsigned mask);
	void setCache(CXMLNodeCache *c);
	void reverseFlags(unsigned mask);
	int setNod(const char *nod,CXMLCodec *xc=0);
	int replaceNod(const char *nod,unsigned len,CXMLCodec *xc=0);

	void setPrev(CXMLNode *p);
	void setNext(CXMLNode *p);
	void setParent(CXMLNode *p);

	unsigned updateParent(CXMLNode *p);

	void appendChild(CXMLNode *p);
	void preppendChild(CXMLNode *p);
	void insertChild(CXMLNode *p,unsigned ref,bool ahead);
	void insertChild(CXMLNode *p,CXMLNode *ref,bool ahead);

	void appendSibling(CXMLNode *p);
	void preppendSibling(CXMLNode *p);
	void insertSibling(CXMLNode *p,int off,bool ahead);
	void insertSibling(CXMLNode *p,bool ahead);

	void appendAttrib(CXMLAttrib *a);
	void preppendAttrib(CXMLAttrib *a);
	void insertAttrib(CXMLAttrib *a,unsigned ref,bool ahead);
	void insertAttrib(CXMLAttrib *a,CXMLAttrib *ref,bool ahead);

	static void setIndent(unsigned indent);

	const char* findVar(const char *what,bool exact=false) const;
	CXMLAttrib* findAttrib(const char *what,unsigned len,bool exact=false) const;
	CXMLNode* findNode(const char *what,unsigned len,unsigned type=0,unsigned depth=1,bool exact=false) const;
	CXMLNode* findChild(const char *what,unsigned len,unsigned type=0,unsigned depth=1,bool exact=false) const;

	CXMLNode* removeLastChild();
	CXMLNode* removeFirstChild();
	CXMLNode* removeChild(CXMLNode& x);
	CXMLNode* removeChildAt(unsigned idx);
	CXMLNode* removeChildrenTree(unsigned *count=0);

	CXMLNode* removeLastSibling();
	CXMLNode* removeFirstSibling();
	CXMLNode* removeSibling(CXMLNode& x);
	CXMLNode* removeSiblingAt(unsigned idx);
	
	CXMLAttrib* removeLastAttrib();
	CXMLAttrib* removeFirstAttrib();
	CXMLAttrib* removeAttrib(CXMLAttrib& a);
	CXMLAttrib* removeAttribAt(unsigned idx);
	CXMLAttrib* removeAttribTree(unsigned *count=0);

	CXMLNode* findOpenTag(const char *nod,unsigned len=0) const;

	int build(const char *nod,...);
	int build(const char *nod,va_list ap);
	int build(const char *nod,CXMLAttrib& a);
	int build(CXMLCodec *xc,const char *nod,unsigned flags=0);//especially for meta node
	//格式符:
	//	| - 新标签作为兄弟节点添加
	//	- - 新标签作为父节点的兄弟节点添加
	//	+ - CXMLNode * 类型的参数
	//	* - CXMLAttrib * 类型的参数
	//	# - const char * 类型的CDATA节点参数
	//	$ - char * 类型的参数
	//	< - 开始新标签(默认是开放标签)
	//	/ - 关闭标签
	//	! - !元标签
	//	? - ?元标签
	//	c,d,l,n,p,s,u,w(ul),x - 数值类型参数
	//	' ' - 标签和属性之间的分隔符
	//	= - 属性和值之间的分隔
	//	/ - 独立标签
	//	> - 结束标签
	//示例:
	//	build("<s s=s/>","iq","type","result") => "<iq type='result'>"
	//	build("<?s s=s?>","xml","version","1.0") => "<?xml version='1.0'?>"
	//	build("<s s=s s=sd><s>s</s>") => "<message to='...' id='msg1'><body>...</body></message>"
	int build(CXMLCodec *xc,const char *nod,const char *fmt,...);
	int build(CXMLCodec *xc,const char *nod,const char *fmt,va_list ap);

	int save(FILE *fp,CXMLCodec *xc=0) const;
	char* toStr(char *p,CXMLCodec *xc=0) const;	//转换成字符串形式
	int load(const char*& b,const char *e,CXMLCodec *xc=0);//转换成内存形式
	int loadTag(const char*& b,const char *e);
	int loadCData(const char*& b,const char *e,CXMLCodec *xc=0);
	int loadComment(const char*& b,const char *e);

	static int findClosePos(const char*& p,const char **r);

	static CXMLNode* load(CXMLNodeCache *xnc,const char*& b,const char *e,int *err,CXMLCodec *xc=0);//转换成内存形式
	int save(const char *path,CXMLCodec *xc,bool overwrite=true) const;
};

inline void CXMLNode::reset(){memset(this,0,sizeof(*this));}

inline CXMLNode::operator char*() const{return (char *)m_nod;}
inline CXMLNode::operator const char*() const{return m_nod;}
inline CXMLNode& CXMLNode::operator=(const char *nod)
{
	if(!setNod(nod)) assert(false);
	return *this;
}
inline CXMLNode& CXMLNode::operator=(const CXMLNode& x)
{
	if(clone(x)) assert(false);
	return *this;
}

inline bool CXMLNode::operator==(const char *nod){return !strcmpi(m_nod,nod);}
inline bool CXMLNode::operator!=(const char *nod){return !((*this)==nod);}
inline bool CXMLNode::operator==(const CXMLNode& x){return isSameTo(x);}
inline bool CXMLNode::operator!=(const CXMLNode& x){return !isSameTo(x);}

inline bool CXMLNode::isRoot() const{return !m_parent && !m_prev;}
inline bool CXMLNode::isLast() const{return !m_next;}
inline bool CXMLNode::isFirst() const{return !m_prev;}
inline bool CXMLNode::isNoChild() const{return !m_children;}
inline bool CXMLNode::isTypeOf(unsigned type) const{return m_type==type;}
inline bool CXMLNode::isNodOf(const char *nod,unsigned len) const
{
	if(len && m_len!=len) return false;
	return !strcmpi(m_nod,nod);
}
inline bool CXMLNode::isDepthOf(unsigned depth) const{return m_depth==depth;}
inline bool CXMLNode::isOpenOf(const char *nod,unsigned len) const
{
	return m_type!=XNT_META
		&& m_type!=XNT_CDATA
		&& !(m_flags & (XNF_CLOSE_TAG|XNF_INDEP_TAG))
		&& (len ? m_len==len : true)
		&& !strcmpi(m_nod,nod);
}
inline bool CXMLNode::isChildOf(const CXMLNode& x) const{return m_parent!=&x;};
inline bool CXMLNode::isParentOf(const CXMLNode& x) const{return x.m_parent==this;}
inline bool CXMLNode::isNodOfExact(const char *nod,unsigned len) const
{
	if(len && m_len!=len) return false;
	return !strcmp(m_nod,nod);
}
inline bool CXMLNode::isTypeOf(const char *nod,unsigned len,unsigned type,bool exact) const
{
	return m_type==type && (len ? m_len==len : true) && (exact ? !strcmpi(m_nod,nod) : !strcmp(m_nod,nod));
}

inline void* CXMLNode::getDummy() const{return m_dummy;}
inline unsigned CXMLNode::getLen() const{return m_len;}
inline unsigned CXMLNode::getBufSize() const{return m_bs;}
inline unsigned CXMLNode::getType() const{return m_type;}
inline unsigned CXMLNode::getDepth() const{return m_depth;}
inline CXMLNode* CXMLNode::getPrev() const{return m_prev;}
inline CXMLNode* CXMLNode::getNext() const{return m_next;}
inline const char* CXMLNode::getNod() const{return m_nod;}
inline CXMLNode* CXMLNode::getParent() const{return m_parent;}
inline unsigned CXMLNode::getAttribs() const{return m_attribs;}
inline unsigned CXMLNode::getChildren() const{return m_children;}
inline CXMLNode* CXMLNode::getLastChild() const{return m_last;}
inline CXMLNode* CXMLNode::getFirstChild() const{return m_first;}
inline CXMLNodeCache* CXMLNode::getCache() const{return m_xnc;}
inline CXMLAttrib* CXMLNode::getLastAttrib() const{return m_tail;}
inline CXMLAttrib* CXMLNode::getFirstAttrib() const{return m_head;}
inline unsigned CXMLNode::getFlags(unsigned mask) const{return (m_flags & mask);}

inline void CXMLNode::resetFlags(){m_flags=0;}
inline void CXMLNode::setDummy(void *p){m_dummy=p;}
inline void CXMLNode::setType(unsigned type){m_type=type;}
inline void CXMLNode::setFlags(unsigned mask){m_flags|=mask;}
inline void CXMLNode::setDepth(unsigned depth){m_depth=depth;}
inline void CXMLNode::clearFlags(unsigned mask){m_flags&=~mask;}
inline void CXMLNode::setCache(CXMLNodeCache *c){m_xnc=c;}
inline void CXMLNode::reverseFlags(unsigned mask){m_flags^=mask;}

inline void CXMLNode::setPrev(CXMLNode *p){m_prev=p;}
inline void CXMLNode::setNext(CXMLNode *p){m_next=p;}
inline void CXMLNode::setParent(CXMLNode *p){m_parent=p;}

inline bool CXMLNode::isAbove(const CXMLNode& x) const{return x.isUnder(*this);}
inline bool CXMLNode::isAttribExist(const char *name,unsigned len,bool exact) const{return findAttrib(name,len,exact)!=0;}
inline bool CXMLNode::isChildExist(const char *nod,unsigned len,unsigned type,unsigned depth,bool exact) const
{
	return findChild(nod,len,type,depth,exact)!=0;
}

#endif//LIBXML_XMLNODE_H

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -