/* 原先的CXmlParse读取xml文件的方式类似深度遍历xml文档树,因此本接口的使用方式类似使用堆栈来进行文档树的分析 */ #pragma once #include #include #include #include "layer.h" #include "pugiconfig.hpp" #include "pugixml.hpp" class AFX_EXT_CLASS CKXmlParse //ggff20250614 { protected: typedef struct _xmlParseNode { CString str; pugi::xml_node node; }KXMLPARSENODE; public: CKXmlParse(void); virtual ~CKXmlParse(void); void Clear(void); BOOL SetXmlFileBuffer(char* pBuffer,ULONG64 bufLen); BOOL ReadXmlFile(char* filePath); //CString ReadFileName(CFile& fr); //读取一串XML,包括关键字及其值 //分析该串XML语句,如果正确将关键字保存在m_strKey中,数值保存在m_valArray中 int ReadBeginSection(); int ReadEndSection(); BOOL IsIncludeValue(void); //读取一串XML的值,结束符号为空格、TAB键、回车及<(标示一新段的开始), 返回值表示是否一个新段的开始 BOOL ReadValue(); //BOOL ReadInner(CFile& fr); //不区分大小写比较键值 BOOL IsKey(CString lpszKeyString); //与当前m_strKey值比较 BOOL IsKey(const CString& key, LPCTSTR lpszKeyString); BOOL ParaseKeyValue(CString strKeyValue, CString& key, CString& val); //分析的字符串以=分隔KEY与VALUE BOOL ParaseKeyValue(int nIndex, CString& key, CString& val); //分析的字符串以=分隔KEY与VALUE int ReadRect( CRect8& rect); //读取矩形范围DML关键写及值 //已经将信息读取到了该类中,仅进行分析并形成需要的元素 int ParaseAndReadRect(CRect8& rect); int ParaseLayer(CLayer* pLayer, void* pxy); int ParaseFont(LOGFONT& logFont, CSize8& size); int ParaseFont(LOGFONT& logFont, CSize8& size, COLORREF& color, int& script); int DML_ParaseHowToViewCurve(CHowToViewCurve* phtv, void* pxy); int DML_ParaseHowToViewPoint(CHowToViewPoint* phtp, void* pxy); int DML_WriteMemoryBlock(CFile& fw, BYTE* lpData, DWORD nDataLength, LPCTSTR strType, int nBaseTabNum = 0); BYTE* DML_ReadMemoryBlock(CFile& fr, DWORD& nOutDataLength, CString& strType); int PCG_ParaseHowToViewCurve(CHowToViewCurve* phtv, void* pxy, std::vector&keys, std::vector&props); int PCG_ParaseHowToViewPoint(CHowToViewPoint* phtp, void* pxy, std::vector&keys, std::vector&props); int PCG_WriteMemoryBlock(CFile& fw, BYTE* lpData, DWORD nDataLength, LPCTSTR strType, const short& ver = 0, int nBaseTabNum = 0); BYTE* PCG_ReadMemoryBlock(DWORD& nOutDataLength, CString& strType); BOOL IsEndSection();// { return m_bOneLineEndSection; } //ggff2025 int ParaseAndReadCoordinate( CPointList& coords); int ParaseAndReadList(); //具体数据保存在m_valArray中 BOOL CurrentNodeHasChild() { return m_bCurrendNodeHasChild; } protected: //int ReadSection(CFile& fr, BOOL bBegin); //读取一串XML,其开始符号为<,结束符号为> //int ReadValueOne(CFile& fr, BOOL *bNewSection); //读取一串XML的值,结束符号为< void ConvertCopy(char * &line,int len, char* &dest); //int ScanfString(CStringArray &m_type, char* str, int len); BOOL m_bIncludeValue; void MakeStrToArr1(CString str, CStringArray &StrArr, CString splitStr); public: BOOL m_bOneLineEndSection; //ggff 2025 用来表示读了一条语句是否是一个完成xml语句,ReadBeginSection只是读取< >中的语句,不区分是否 < > 和< /> 所以增加这个(用于区分这两种情况) CString m_strKey; std::vector<CString> m_valArray; //存放一个节点的所有属性名称 std::vector<CString> m_propValArray;// 存放一个节点的所有属性值 CString m_nodeStrValue; CString FormatFontDML(LOGFONT& lf, CSize8& size, LPCTSTR elementName = nullptr); CString FormatFontPCG(LOGFONT& lf, CSize8& size); CString FormatFontPCG(LOGFONT& lf, CSize8& size, COLORREF& color, int script); void SetDelimiter(char c) { m_cDelimiter = c; }; //ggff2025 xml文件中有时需要读取多行文本,将多行文本的分隔符号设置一下。 static CString SetEscapeCharToChar(CString& str); //替换文本中转义字符 ggff2025 static CString SetCharToEscapeChar(CString& str); protected: char m_cDelimiter; pugi::xml_document m_xmlDoc; BOOL m_bHaveXml; pugi::xml_node m_CurrentNode; //pugi::xml_node_iterator m_CurrentNodeIt; //pugi::xml_node m_ParentNode; //std::stack< pugi::xml_node_iterator> m_nodeItStack; std::list< KXMLPARSENODE> m_nodeList; void InitRootNode(); BOOL m_bUtf8; //bool hasUtf8Bom(const std::string& filename); //bool isUtf8Declared(const pugi::xml_document& doc); BOOL isUtf8(CString strPathName); BOOL m_bCurrendNodeHasChild; };