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

📄 xml.cpp

📁 PC与PDA数据交互系统的原代码 仅供参考.非本人所编写的
💻 CPP
字号:
#include "xml.h"

#define C_SPACE		_T(' ')
#define C_LMARK		_T('<')
#define C_RMARK		_T('>')
#define C_LF		0x0a
#define C_CR		0x0d
#define C_TAB		_T('\t')

#define S_SPACE		_T(" ")
#define S_LMARK		_T("<")
#define S_RMARK		_T(">")
#define S_ENDL		_T("\n")
#define S_TAB		_T("\t")

#define S_EMPTY		_T("")



CIn_XML::CIn_XML()
{
	m_isOpen = FALSE;
}

CIn_XML::~CIn_XML()
{
	Close();
}

void CIn_XML::Open(const CString xmlFile, int &nOpened, CString rootName)
{
	nOpened = m_root.Open(xmlFile, rootName);
	m_isOpen = nOpened;
}

int	CIn_XML::Is_open()
{
	return m_isOpen;
}

void CIn_XML::Close()
{
	m_table.RemoveAll();
	m_root.Close();
}

void CIn_XML::WriteNode(CXmlNode &Node, COut_XML *pOutXML)
{
	if (Node.m_subNodes.GetSize()) {
		pOutXML->PutHead(Node.m_nodeName);
		for (int i=0; i<Node.m_subNodes.GetSize(); i++) {
			WriteNode(Node.m_subNodes[i], pOutXML);
		}
		pOutXML->PutTail(Node.m_nodeName);
	}
	pOutXML->PutItem(Node.m_nodeName, Node.m_nodeValue);
}

BOOL CIn_XML::SaveTo(const CString xmlFile)
{
	COut_XML *pOutXML;
	BOOL bOpened;
	pOutXML=new COut_XML;
	pOutXML->Open(xmlFile, bOpened);
	if (!bOpened) {
		delete pOutXML;
		return FALSE;
	}

	for (int i=0; i<m_root.m_subNodes.GetSize(); i++){
		WriteNode(m_root.m_subNodes[i], pOutXML);
	}

	delete pOutXML;
	return TRUE;
}

int	CIn_XML::FindRecords(const CString infoType, const CString recordType, int &RecordsCount)
{
	RecordsCount = FindRecords(infoType, recordType);
	return RecordsCount;
}

int	CIn_XML::FindRecords(const CString infoType, int &RecordsCount)
{
	RecordsCount = FindRecords(infoType);
	return RecordsCount;
}

int	CIn_XML::FindRecords(const CString infoType, const CString recordType)
{
	m_table.RemoveAll();
	m_root.GetNodesTable(m_table, infoType, recordType);
	return m_table.GetSize();
}

int	CIn_XML::FindRecords(const CString infoType)
{
	m_table.RemoveAll();
	m_root.GetNodesTable(m_table, infoType);
	return m_table.GetSize();
}

int	CIn_XML::GetRecordsCount(int &RecordsCount)
{
	RecordsCount = m_table.GetSize();
	return RecordsCount;
}

CString CIn_XML::GetRecordPath(int recordNo, LPTSTR RecordPath)
{
	CString Path = GetRecordPath(recordNo);
	_tcscpy(RecordPath, (LPCTSTR)Path);
	return Path;
}

CString CIn_XML::GetRecordPath(int recordNo)
{
	if ((recordNo>=0) && (recordNo<m_table.GetSize())) {
		return m_table[recordNo].m_path;
	}
	else {
		return S_EMPTY;
	}
}

CString CIn_XML::GetPath(int recordNo)
{
	return GetRecordPath(recordNo);
}

CString CIn_XML::GetItemValue(int recordNo, const CString itemName, LPTSTR ItemValue)
{
	CString Value = GetItemValue(recordNo, itemName);
	_tcscpy(ItemValue, (LPCTSTR)Value);
	return Value;
}

CString CIn_XML::GetItemValue(int recordNo, const CString itemName)
{
	if ((recordNo>=0) && (recordNo<m_table.GetSize())) {
		if (itemName==_T("_FILE_"))
			return m_table[recordNo].m_pNode->m_nodeValue;
		else
			return m_table[recordNo].m_pNode->GetFldValue(itemName);
	}
	else {
		return S_EMPTY;
	}
}

CString CIn_XML::GetFile(int recordNo)
{
	return GetItemValue(recordNo, "_FILE_");
}


int	CIn_XML::GetInfoTable(CStringTable &InfoTable)
{
	InfoTable.RemoveAll();
	int n=m_root.m_subNodes.GetSize();
	for (int i=0; i<n; i++) {
		InfoTable.Add(CString(m_root.m_subNodes[i].m_nodeName));
	}
	return n;
}

CXmlNode::CXmlNode()
{
	m_nodeName = S_EMPTY;
	m_nodeValue = S_EMPTY;
}

CXmlNode::CXmlNode(CString name, CString value)
{
	m_nodeName = name;
	m_nodeValue = value;
}

void CXmlNode::CopyFrom(const CXmlNode& other)
{
	RemoveAll();
	m_nodeName = other.m_nodeName;
	m_nodeValue = other.m_nodeValue;
	for (int i=0; i<other.m_subNodes.GetSize(); i++) {
		m_subNodes.Add(other.m_subNodes[i]);
	}
}

CXmlNode::CXmlNode(const CXmlNode& other)
{
	CopyFrom(other);
}

CXmlNode& CXmlNode::operator = (const CXmlNode& other)
{
	CopyFrom(other);
	return *this;
}

void CXmlNode::RemoveAll( )
{
	for (int i=0; i<m_subNodes.GetSize(); i++) {
		m_subNodes[i].RemoveAll();
	}
	m_subNodes.RemoveAll();
	m_nodeName = S_EMPTY;
	m_nodeValue = S_EMPTY;
}

CXmlNode::~CXmlNode()
{
	RemoveAll();
}

CInFile::CInFile(CString fileName)
{
	m_hFile = CreateFile( fileName , GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); 
	m_bEof = !isOpen();
	m_line = S_EMPTY;
}

CInFile::~CInFile()
{
	CloseHandle(m_hFile);
	m_hFile = INVALID_HANDLE_VALUE;
}

BOOL CInFile::isOpen()
{
	return (m_hFile!=INVALID_HANDLE_VALUE);
}

BOOL CInFile::eof()
{
	return (m_line.IsEmpty() && (m_bEof));
}

#define LINESIZE 256
void CInFile::getline()
{
	TCHAR buf[LINESIZE+1];
	DWORD n;
	BOOL bResult;
	while ( ((m_line.Find(S_LMARK)<0) || (m_line.Find(S_RMARK)<0)) && (!eof()))
	{
		bResult = ReadFile(m_hFile, &buf, sizeof(buf)-sizeof(TCHAR), &n, NULL) ; 
		// Check for end of file. 
		n=n / sizeof(TCHAR);
		m_bEof = (bResult &&  n==0); 
		buf[n] = 0;
		WORD *p=(WORD *)buf;
		if (*p==0xFEFF) 
			m_line = m_line + (buf+1);
		else
			m_line = m_line + buf;
	}
	if ((m_line.Find(S_LMARK)<0) || (m_line.Find(S_RMARK)<0))
		m_line = S_EMPTY;
}

CString	CInFile::getItem()
{
	getline();
	if (eof()) 
		return S_EMPTY;

	TCHAR *p, *q, *buf;

	TCHAR a[]=_T("\n");

	buf=m_line.GetBuffer(m_line.GetLength());

	// skip any space before "<"
	p = buf;
	while ((*p!=C_LMARK) && ((*p==C_SPACE)||(*p==C_CR)||(*p==C_LF)||(*p==C_TAB)))
		p++;
	if (*p!=C_LMARK) p=buf;

	if (*p==C_LMARK) {
		q=p;
		while (*p!=C_RMARK) p++;
	} else {
		while ((*p==C_CR)||(*p==C_CR)) p++;
		q=p;
		while (*p!=C_LMARK) p++; 
		p--;
		while ((*p==C_SPACE)||(*p==C_CR)||(*p==C_LF)||(*p==C_TAB)) p--;
	}
    
	m_line.ReleaseBuffer();
	CString item=m_line.Mid(q-buf, p-q+1);
    m_line.Delete(0, p-buf+1);

	TRACE(_T("%s\n"), item);
	return item;
}

BOOL CXmlNode::Open(CString filename, CString rootName)
{
	CInFile inFile(filename);
	rootName=S_LMARK+rootName+S_RMARK;
	CString item;
	if (inFile.isOpen()) {
		do {
			item = inFile.getItem();
		} while (item!=rootName);
  		return LoadXMLNode(inFile, item);
	}
	return FALSE;
}

#define ITEM_HEAD _T('H')
#define ITEM_DATA _T('D')
#define ITEM_TAIL _T('T')

TCHAR getItemType(CString &item)
{
	if (item.Left(2)==_T("</")) 
		return ITEM_TAIL;
	if (item.Left(1)==_T("<"))
		return ITEM_HEAD;
	return ITEM_DATA;
}

CString trimFlag(CString item)
{
	if (item[0]==_T('<')) {
		item.Delete(0); 
		if (item[0]==_T('/')) item.Delete(0);
		item.Delete(item.GetLength()-1);
	}
	return item;
}

BOOL CXmlNode::LoadXMLNode(CInFile& inFile, CString head)
{
	int i;
	CString item;
	TCHAR itemType;

	if (m_nodeName.IsEmpty()) m_nodeName=trimFlag(head);
	else {
		i = m_subNodes.Add(CXmlNode());
		m_subNodes[i].LoadXMLNode(inFile, head);
	}
	while (!inFile.eof()) {
		item = inFile.getItem();
		itemType = getItemType(item);
		if (itemType==ITEM_HEAD) {
			i = m_subNodes.Add(CXmlNode());
			m_subNodes[i].LoadXMLNode(inFile, item);
		} 
		else if (itemType==ITEM_DATA) {
			m_nodeValue = item;
		}
		else if (itemType==ITEM_TAIL) {
			return TRUE;
		}
	}
	return TRUE;
}

void CXmlNode::FindNodes(CXmlFindTable& table, CString what, CString path, int level)
{
	if (what.IsEmpty() && ((m_nodeName==_T("_RECORD_")) || (m_nodeName==_T("_FILE_"))))
		table.Add(CFindItem(path, this));
	else if (m_nodeName==what)
		table.Add(CFindItem(path, this));
	else {
		if (level!=0) {
			if (path.IsEmpty()) path=m_nodeName;
			else path = path + _T("\\") + m_nodeName;
		}
		for (int i=0; i<m_subNodes.GetSize(); i++) 
		{
			m_subNodes[i].FindNodes(table, what, path, level+1);
		}
	}
}

CXmlNode* CXmlNode::Locate(CString what)
{
    int i;
	if (m_nodeName==what) {
		return this; 
	} 
	else {
		for (i=0; i<m_subNodes.GetSize(); i++) {
			if (m_subNodes[i].m_nodeName==what)
				return &m_subNodes[i];
		}
		for (i=0; i<m_subNodes.GetSize(); i++) {
			CXmlNode* node;
			node = m_subNodes[i].Locate(what);
			if (node!=NULL) return node;
		}
	}
	return NULL;
}

CString CXmlNode::GetFldValue(const CString fldName)
{
	CString fldValue=S_EMPTY;
	for (int i=0; i<m_subNodes.GetSize(); i++) {
		if (m_subNodes[i].m_nodeName==fldName) {
			fldValue = m_subNodes[i].m_nodeValue;
			break;
		}
	}
	return fldValue;
}

void CXmlNode::GetNodesTable(CXmlFindTable& table, const CString infoType, const CString recType)
{
	CXmlNode *node;
	table.RemoveAll();
	node = Locate(infoType);
	if (node) node->FindNodes(table, recType, S_EMPTY, 0);
}

void CXmlNode::GetNodesTable(CXmlFindTable& table, const CString infoType)
{
	CXmlNode *node;
	table.RemoveAll();
	node = Locate(infoType);
	if (node) {
		node->FindNodes(table, S_EMPTY, S_EMPTY, 0);
	}
}

void CXmlNode::Close()
{
	RemoveAll();
}

COut_XML::COut_XML()
{
	m_level = 0;
}

COut_XML::~COut_XML()
{
	Close();
}

void COut_XML::WriteLn(const CString s)
{
	if (m_hFile!=INVALID_HANDLE_VALUE) {
		DWORD n;
		CString list = s + _T("\n");
		WriteFile(m_hFile, (LPCTSTR) list, sizeof(TCHAR)*list.GetLength(), &n, NULL);
	}
}

void COut_XML::Open(const CString xmlFileName, int &nOpened, CString rootName)
{
	m_hFile = CreateFile(	xmlFileName,
							GENERIC_WRITE,
							FILE_SHARE_READ,
							NULL,
							CREATE_ALWAYS,
							FILE_ATTRIBUTE_NORMAL,
							NULL);

	m_level = 0;
	m_rootName = rootName;
	if (m_hFile!=INVALID_HANDLE_VALUE)
	{
		WriteLn(_T("<?xml version=\"1.0\" encoding=\"GB2312\" standalone=\"yes\"?>"));
		WriteLn(_T("<")+m_rootName+_T(">"));
		m_level++;
	}
	nOpened = (m_hFile!=INVALID_HANDLE_VALUE);
}

int COut_XML::Is_open()
{
	return (m_hFile!=INVALID_HANDLE_VALUE);
}

void COut_XML::Close()
{
	DWORD n;
	if (Is_open()) {
		m_level--;
		CString list=_T("</")+m_rootName+_T(">\n");
		WriteFile(m_hFile, (LPCTSTR) list, sizeof(TCHAR)*list.GetLength(), &n,NULL);
		CloseHandle( m_hFile );
		m_hFile = INVALID_HANDLE_VALUE;
	}
}



void COut_XML::PutHead(const CString name)
{
	if (Is_open()) {
		WriteLn(tab() + _T("<") + name +_T(">"));
		m_level++;
	}
}

void COut_XML::PutTail(const CString name)
{
	if (Is_open()) {
		m_level--;
		WriteLn(tab() + _T("</") + name +_T(">"));
	}
}


void COut_XML::PutItem(const CString name, const CString value)
{
	if ((Is_open()) && (!value.IsEmpty())) {
		WriteLn(tab() + _T("<") + name + _T(">") + value + _T("</") + name + _T(">"));
	}
}

CString COut_XML::tab()
{
	CString s=_T("");
	for (int i=0; i<m_level; i++) s+=_T("    ");
	return s;
}

void COut_XML::PutRecordHead()
{
	PutHead(_T("_RECORD_"));
}

void COut_XML::PutRecordTail()
{
	PutTail(_T("_RECORD_"));
}

void COut_XML::PutFile(const CString fileName)
{
	PutItem(_T("_FILE_"), fileName);
}

⌨️ 快捷键说明

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