`
baiguomeng
  • 浏览: 998181 次
文章分类
社区版块
存档分类
最新评论

利用XML文件的一个写日志的类!!!!!

 
阅读更多

对于程序执行期间的错误跟踪!相信大家都有自己的一套办法!!!但都是利用文件文件,我这次利用的是XML&XSL,可产生报表格式的日志,轻松生成报表!!!

我参考了Emilio Guijarro Cameros的CXMLProfile写XML配置文件的思想!!!利用XML 接口IXMLDOMDocumentIXMLDOMNodeIXMLDOMElement和 MFC相结合,写成了一个CXMLLogfile类,只暴露了两个公共方法

void Log(LPCTSTR lpszFilName,LPCTSTR s,...);
bool ClearAll()

Log是添加一条日志,ClearAll是清除所有日志!!!当大家需要查看日值时,只需要打开相应的XML文件Log.XML就可以看到一个日志表格了,为此我专门写了一个XSL样式文件(XML样式XSL文件必须在XML文件同一目录下)!

以下是源代码,需要IE5.5以上支持!!!如果编译错误!请下载微软的最新XML SDK!!!!


// XMLLogfile.h: interface for the CXMLLogfile class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_XMLLOGFILE_H__EA8ACC84_7139_49F6_9B8A_F69D9CF5C385__INCLUDED_)
#define AFX_XMLLOGFILE_H__EA8ACC84_7139_49F6_9B8A_F69D9CF5C385__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include
#include
#include
#include
#include

//Author : By force eagle
//Date time : 2003-5-26 17:08
//reference :
//CXMLProfile By Emilio Guijarro Cameros

#pragma comment(lib,"msxml2.lib")
class CXMLLogfile : public CObject
{
CString m_strFileName;
IXMLDOMDocument *m_pXMLDoc;

IXMLDOMNode * GetChildNode(LPCTSTR lpszParent, LPCTSTR lpszChild,BOOL bCreate = TRUE);
IXMLDOMNode * GetFirstLevelNode(LPCTSTR lpszNodeName,BOOL bCreate = TRUE);

// UNIX timestamp: seconds from 1970-01-01 00:00:00 (UTC)
inline double TimeStamp(void)
{
_timeb ts;
_ftime( &ts );
return (int)ts.time + (ts.millitm/1000.0);
};
protected:
void AppendNode(IXMLDOMNode * pXMLItem, LPCTSTR lpszNodeName, LPCTSTR lpszValue);
void AppendItem(LPCTSTR lpszFileName,LPCTSTR lpszComment);

void Flush();

bool CreateLogFile(LPCTSTR lpszLogFilName);

void DumpComError(_com_error &e);

void Init();


public:
CXMLLogfile(LPCTSTR lpszFileName = NULL);
virtual ~CXMLLogfile();
void Log(LPCTSTR lpszFilName,LPCTSTR s,...);
bool ClearAll();
};

#endif // !defined(AFX_XMLLOGFILE_H__EA8ACC84_7139_49F6_9B8A_F69D9CF5C385__INCLUDED_)


// XMLLogfile.cpp: implementation of the CXMLLogfile class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "XMLLogfile.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
/*
static TCHAR *szLogOrig= {_T("<!--l version=/"1.0/" encoding=/"GB2312/-->/n"
"<!--l-stylesheet href=/"Log.xsl/" type=/"text/xsl/-->/n"
"/nXXXX/n1053925276.381/n"
"2003-05-26/n13:01:16.861/n/n")};
//*/
static WCHAR *wszLogOrig = {L"<!--l version=/"1.0/" encoding=/"GB2312/-->/n<!--l-stylesheet href=/"Log.xsl/" type=/"text/xsl/-->/n/nXXXX/n1053925276.381/n2003-05-26/n13:01:16.861/n/n"};

CXMLLogfile::CXMLLogfile(LPCTSTR lpszFileName)
{
VARIANT_BOOL bResult;
IXMLDOMElement *pRootNode;
HRESULT hr;
if (NULL == lpszFileName)
{
CString strHlpPath ,strAppName;
strHlpPath = AfxGetApp()->m_pszHelpFilePath;
strAppName = AfxGetAppName();
strHlpPath = strHlpPath.Left(strHlpPath.GetLength() - 4
- strAppName.GetLength());
m_strFileName = strHlpPath + _T("LOG.XML");
}
else
{
m_strFileName = lpszFileName;
}

hr = CoInitialize(NULL);
LoadLog:
if(SUCCEEDED(hr))
{
hr = CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER,
IID_IXMLDOMDocument, (void**)&m_pXMLDoc);
if(SUCCEEDED(hr))
{
m_pXMLDoc->load(COleVariant(m_strFileName), &bResult);
}
}

//取得根节点
m_pXMLDoc->get_documentElement(&pRootNode);

if(pRootNode == NULL)//无根节点
{
m_pXMLDoc->Release();
m_pXMLDoc = NULL;
//重新创建XML日值文件
CreateLogFile(m_strFileName);
goto LoadLog; //重新载入
}
else
{
Init();
}
}

CXMLLogfile::~CXMLLogfile()
{
m_pXMLDoc->save(COleVariant(m_strFileName));
m_pXMLDoc->Release();
}
/*
*函数名称:Init()
*说明:初始化XML日志文件的工程信息
*参数:
*无
*返回:无
*/
void CXMLLogfile::Init()
{
IXMLDOMNode *pAppNameNode, *pTimestamp, *pDate, *pTime;;
TCHAR *szTemp = new TCHAR[MAX_PATH];
HRESULT hr ;

CTimetimeCur ;
timeCur = CTime::GetCurrentTime();
CString strDate, strTime;
strDate = timeCur.Format(_T("%Y-%m-%d"));
strTime = timeCur.Format(_T("%X"));

//更改工程名称
pAppNameNode = GetFirstLevelNode(_T("AppName"));
hr = pAppNameNode->put_text(CComBSTR(AfxGetAppName()));
pAppNameNode->Release();
//*
//时间戳
ZeroMemory(szTemp,MAX_PATH);
double timestamp = TimeStamp();
_stprintf(szTemp,_T("%.3f"),timestamp);
pTimestamp = GetFirstLevelNode(_T("Timestamp"));
hr = pTimestamp->put_text(CComBSTR(szTemp));
pTimestamp->Release();
//*/
//日期
pDate = GetFirstLevelNode(_T("Date"));
hr = pDate->put_text(CComBSTR(strDate));
pDate->Release();

//时间
pTime = GetFirstLevelNode(_T("Time"));
hr = pTime->put_text(CComBSTR(strTime));
pTime->Release();

delete szTemp;
Flush();
}
/*
*函数名称:DumpComError(_com_error &e)
*说明:输出COM错误信息
*参数:
*IN _com_error &eCOM错误信息对象
*返回:无
*/
void CXMLLogfile::DumpComError(_com_error &e)
{
_bstr_t bstrSource(e.Source());
_bstr_t bstrDescription(e.Description());

TRACE("Error/n");
TRACE("/tCode = %08lx/n", e.Error());
TRACE("/tCode meaning = %s/n", e.ErrorMessage());
TRACE("/tSource = %s/n", (LPCSTR) bstrSource);
TRACE("/tDescription = %s/n", (LPCSTR) bstrDescription);
}
/*
*函数名称:CreateLogFile(LPCTSTR lpszLogFilName)
*说明:创建原始的XML日志文件
*参数:
*IN LPCTSTR lpszLogFileName 文件名称
*返回:true 成功
*/
bool CXMLLogfile::CreateLogFile(LPCTSTR lpszLogFilName)
{
IXMLDOMDocument *pXMLDoc = NULL;

BSTRbstr = NULL;
VARIANT_BOOLstatus;
HRESULT hr;

try
{
hr = CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER,
IID_IXMLDOMDocument, (void**)&pXMLDoc);

if (FAILED(hr))
_com_issue_error(hr);

bstr = ::SysAllocString(wszLogOrig);
ASSERT(NULL != bstr);
hr = pXMLDoc->loadXML(bstr,&status);
::SysFreeString(bstr);

if (FAILED(hr))
_com_issue_error(hr);

if(status != VARIANT_TRUE)
{
return false;
}

hr = pXMLDoc->save(COleVariant(lpszLogFilName));
if (FAILED(hr))
_com_issue_error(hr);

pXMLDoc->Release();
}
catch(_com_error &e)
{
DumpComError(e);
return false;
}
return true;
}
/*
*函数名称:GetFirstLevelNode(LPCTSTR lpszNodeName)
*说明:根据名称查找第一层子节点指针,没有则判断是否创建
*参数:
*IN LPCTSTR lpszNodeName 节点名称
*IN BOOLbCreate 是否创建
*返回:IXMLDOMNode *节点指针
*/
IXMLDOMNode * CXMLLogfile::GetFirstLevelNode(LPCTSTR lpszNodeName,BOOL bCreate)
{
IXMLDOMElement *pRootNode = NULL, *element = NULL;
IXMLDOMNode *pLogItem = NULL, *pResultNode = NULL;
CComBSTR szName;
bool bSecFound = false, bEntryFound = false;
//wchar_t *szTemp = new wchar_t[255];

m_pXMLDoc->get_documentElement(&pRootNode);

for(pRootNode->get_firstChild(&pLogItem); pLogItem != NULL; pLogItem->get_nextSibling(&pLogItem))
{
pLogItem->get_baseName(&szName);

if(szName == CComBSTR(lpszNodeName))
{
pResultNode = pLogItem;
break;
}
}

if(pLogItem == NULL && bCreate)
{
m_pXMLDoc->createElement(CComBSTR(lpszNodeName), &element);
pRootNode->appendChild(element, &pLogItem);
element->Release();
pResultNode = pLogItem;
}

pRootNode->Release();

return pResultNode;
}
/*
*函数名称:GetChildNode(LPCTSTR lpszParent, LPCTSTR lpszChild)
*说明:查找父节点下的某一子节点指针,没有则判断是否创建创建
*参数:
*IN LPCTSTR lpszParent 父节点名称
*INLPCTSTR lpszChild子节点名称
*IN BOOLbCreate 是否创建
*返回:IXMLDOMNode *子节点指针
*/
IXMLDOMNode * CXMLLogfile::GetChildNode(LPCTSTR lpszParent, LPCTSTR lpszChild,BOOL bCreate)
{
IXMLDOMElement *pRootNode= NULL, *element= NULL;
IXMLDOMNode *pLogItem= NULL, *pLogData= NULL, *pResultNode= NULL;
CComBSTR szName;

m_pXMLDoc->get_documentElement(&pRootNode);

for(pRootNode->get_firstChild(&pLogItem); pLogItem != NULL; pLogItem->get_nextSibling(&pLogItem))
{
pLogItem->get_baseName(&szName);

if(szName == CComBSTR(lpszParent))
{
for(pLogItem->get_firstChild(&pLogData); pLogData != NULL; pLogData->get_nextSibling(&pLogData))
{
pLogData->get_baseName(&szName);

if(szName == CComBSTR(lpszChild))
{
pResultNode = pLogData;
break;
}
}

if(pLogData == NULL && bCreate)
{
m_pXMLDoc->createElement(CComBSTR(lpszChild), &element);
pLogItem->appendChild(element, &pLogData);
element->Release();
pResultNode = pLogData;
}
pLogItem->Release();
break;
}
}

if(pLogItem == NULL && bCreate)
{
m_pXMLDoc->createElement(CComBSTR(lpszParent), &element);
pRootNode->appendChild(element, &pLogItem);
element->Release();
m_pXMLDoc->createElement(CComBSTR(lpszChild), &element);
pLogItem->appendChild(element, &pLogData);
element->Release();
pResultNode = pLogData;
}

pRootNode->Release();

return pResultNode;
}
/*
*函数名称:AppendNode(IXMLDOMNode * pXMLItem, LPCTSTR lpszNodeName, LPCTSTR lpszValue)
*说明:在XML中添加一节点,并赋值为 lpszValue
*参数:
*IN IXMLDOMNode *pXMLItem 要添加节点的节点指针
*INLPCTSTR lpszNodeName添加的节点名称
*IN LPCTSTR lpszComment值
*/
void CXMLLogfile::AppendNode(IXMLDOMNode * pXMLItem, LPCTSTR lpszNodeName, LPCTSTR lpszValue)
{
IXMLDOMElement *element;
IXMLDOMNode *pLogData;

m_pXMLDoc->createElement(CComBSTR(lpszNodeName),&element);
pXMLItem->appendChild(element,&pLogData);
element->Release();

pLogData->put_text(CComBSTR(lpszValue));
pLogData->Release();
}
/*
*函数名称:AppendItem(LPCTSTR lpszFileName,LPCTSTR lpszComment)
*说明:在XML中添加一条日志
*参数:
*INLPCTSTR lpszFileName文件信息
*IN LPCTSTR lpszComment错误信息
*/
void CXMLLogfile::AppendItem(LPCTSTR lpszFileName,LPCTSTR lpszComment)
{
IXMLDOMElement *pRootNode, *element;
IXMLDOMNode *nLogItem;
CComBSTR szName;
HRESULT hr;

CTime timeCur ;
timeCur = CTime::GetCurrentTime();
CString strDate, strTime;
strDate = timeCur.Format(_T("%Y-%m-%d"));
strTime = timeCur.Format(_T("%X"));

hr = m_pXMLDoc->get_documentElement(&pRootNode);

m_pXMLDoc->createElement(CComBSTR(_T("LogItem")),&element);
pRootNode->appendChild(element,&nLogItem);
element->Release();

AppendNode(nLogItem,_T("Date"),strDate);

AppendNode(nLogItem,_T("Time"),strTime);

AppendNode(nLogItem,_T("Filename"),lpszFileName);

AppendNode(nLogItem,_T("comment"),lpszComment);


pRootNode->Release();
}
/*
*函数名称:Flush()
*说明:将缓冲区内数据写到磁盘保存XML文件
*参数:
*无
*/
void CXMLLogfile::Flush()
{
m_pXMLDoc->save(COleVariant(m_strFileName));
}
/*
*函数名称:Log(LPCTSTR lpszFilName,LPCTSTR s,...)
*说明:添加一条日值记录
*参数:
*LPCTSTR lpszFileName文件信息
*LPCTSTRs其他错误信息
*EXAMPLE:
*Log(__FILE__,"%ld line error!!",__LINE__)
*/
void CXMLLogfile::Log(LPCTSTR lpszFilName,LPCTSTR s,...)
{
static TCHAR szBuff[1024];
va_list argptr;
int cnt;

va_start(argptr, s);
cnt = _vstprintf(szBuff, s, argptr);
va_end(argptr);

AppendItem(lpszFilName,szBuff);
Flush();
}
/*
*函数名称:ClearAll()
*说明:清除日值
*参数:
*无
*返回值: 成功 true
*/
bool CXMLLogfile::ClearAll()
{
IXMLDOMElement *pRootNode= NULL;
IXMLDOMNode *pLogItem= NULL, *pLogData= NULL, *pOldNode= NULL, *pNextNode ,*pPreviousNode;
CComBSTR szName;
HRESULThr ;
m_pXMLDoc->get_documentElement(&pRootNode);
try
{
pRootNode->get_lastChild(&pLogItem);
do
{
pLogItem->get_previousSibling(&pPreviousNode);

pLogItem->get_baseName(&szName);
if(szName == CComBSTR(_T("LogItem")))
{
pLogItem->get_firstChild(&pLogData);
do
{
pLogData->get_nextSibling(&pNextNode);

pLogData->get_baseName(&szName);
hr = pLogItem->removeChild(pLogData,&pOldNode);
if (FAILED(hr))
_com_issue_error(hr);
pOldNode->Release();
pOldNode = NULL;

pLogData = pNextNode;
}while(pLogData != NULL);
}
hr = pRootNode->removeChild(pLogItem,&pOldNode);

if (FAILED(hr))
_com_issue_error(hr);

pLogItem = pPreviousNode;
}while(pLogItem != NULL);
pRootNode->Release();
}
catch(_com_error &e)
{
pRootNode->Release();
DumpComError(e);
return false;
}
Flush();
return true;
}

分享到:
评论

相关推荐

    商业编程-源码-利用XML文件写日志的类.zip

    在给定的“商业编程-源码-利用XML文件写日志的类.zip”压缩包中,包含了一个专门用于将日志信息写入XML文件的类。这种做法相较于传统的文本日志,提供了更结构化的数据存储方式,方便后期的数据分析和检索。 首先,...

    xml c++ tinyxml xml读写 日志记录 vc mfc

    在C++中实现日志记录,可以创建一个简单的日志类,包含打开、写入、关闭日志文件的方法。MFC提供了一些方便的类,如CFile,可以用于文件操作,CStdString用于字符串处理,这些都能简化日志系统的实现。 具体实现时...

    格式化xml字符串,并生成xml文件

    在实际应用中,我们可能先使用`XMLFileUtil.readFileToString()`方法读取XML文件为字符串,然后通过`XMLFormatUtil.formatXML()`对这个字符串进行格式化,最后再写回为一个新的XML文件。 总结起来,本文主要讨论了...

    C# 类转XML ,XML 转类 日志记录

    例如,我们定义一个类`Person`,包含属性`Name`和`Age`,然后创建一个`Person`对象,`XmlSerializer`可以将其转换为XML字符串,使得数据以可读性强的格式呈现。 ```csharp [Serializable] public class Person ...

    c,c++高手实现xml文件读写解析底层

    - **DOM(Document Object Model)解析**:将整个XML文档加载到内存中形成一个树形结构,便于遍历和操作。但DOM解析消耗资源较大,适合小规模文件。 - **SAX(Simple API for XML)解析**:事件驱动模型,逐行读取...

    C#写日志文件

    以下是一个简单的配置示例,它定义了一个将日志写入文本文件的appender: ```xml , log4net"/&gt; &lt;!-- 其他配置... --&gt; ``` 这个配置会创建一个名为"FileAppender"的appender,将日志...

    一个基于XML的Log框架.rar_STL_c+ log stl_c+ stl log_xml_文件 操作

    标题中的“一个基于XML的Log框架.rar_STL_c+ log stl_c+ stl log_xml_文件 操作”表明这是一个关于使用C++编程语言,并结合STL(Standard Template Library,标准模板库)来创建一个日志框架,且该框架与XML文件操作...

    简单Java&XML数据库版网络日志

    本项目名为"简单Java&XML数据库版网络日志",其核心是利用Java的反射机制来处理XML文件,实现一个网络日志系统。下面将详细介绍这个项目中的关键知识点。 首先,我们来理解Java反射机制。反射是Java提供的一种强大...

    C# 服务 多线程 XMl读写

    综上所述,这个压缩包中的内容可能包含一个使用C#编写的后台服务,该服务利用多线程处理任务,并可能涉及到XML文件的读写操作。服务可能是为了执行周期性任务,如数据采集、日志记录或监控,而多线程技术确保了服务...

    spring,springmvc,mybatis基于xml文件整合(2)

    这样,我们就实现了Spring、Spring MVC和MyBatis的集成,利用XML配置文件定义了Mapper接口与SQL的映射,简化了数据库访问的编码工作。通过Spring的依赖注入机制,我们可以在整个应用中轻松地使用这些Mapper,提高了...

    tinyxml2 version2,c++程序管理xml读写最方便的库

    - XML文件的解析:提取XML文件中的特定信息,如XML日志分析。 - XML生成:动态创建XML结构,用于生成报告或其他需要XML格式的数据。 总的来说,TinyXML2是一个小巧且功能强大的XML处理库,特别适合那些需要快速、轻...

    VC读写xmlDemo

    这个"VC读写xmlDemo"程序作为一个学习资源,可能会包含一个简单的用户界面,通过按钮触发读取和写入操作,以及显示或更新XML文件的内容。开发者可以通过调试和分析代码,深入理解XML与MFC结合的工作原理。 总之,这...

    log4j 写多个日志文件,按照日期每天都记

    在我们的需求中,我们需要为每一天创建一个单独的日志文件,所以需要为每一天定义一个Appender。Appender可以通过`&lt;appender&gt;`标签进行配置,例如: ```properties log4j.appender.dailyFileAppender=org.apache....

    读写Excel jxl.jar 读xml (log4j 文件上传下载笔记).rar

    这篇文档将深入探讨Java中如何使用jxl.jar库进行Excel文件的读写操作,解析XML文件,以及关于log4j的日志记录系统和文件的上传下载笔记。在现代的IT环境中,这些技能对于数据处理、日志管理和系统交互至关重要。 ...

    xml解析类CMarkup

    CMarkup是一个C++编写的XML解析库,它允许开发者在C++环境中处理XML文档,提供了友好的API来操作XML结构。CMarkup不仅支持中文字符,而且易于使用,使得XML解析在C++项目中变得更为便捷。 CMarkup的核心功能包括: ...

    操作xml和excel文件

    例如,你可以使用DOM4J的`DocumentHelper`来解析XML文件,然后利用XPath表达式如`//element_name`来选取特定元素。 2. **JXL对Excel读写**:JXL是Java中广泛使用的库,用于读取和写入Excel文件(.xls格式)。它可以...

    异步写日志

    一种常见的方法是使用Java的ExecutorService,创建一个固定大小的线程池,将日志写入操作封装为Runnable或Callable任务提交到线程池。另一种方法是使用异步日志库,如Log4j2的AsyncAppender,它内部使用了Disruptor...

    JPA 基本jar 文件 附带mysql-`jar文件和persistence.xml配置文件

    - `slf4j-api-1.6.1.jar`: Simple Logging Facade for Java(SLF4J)是一个日志记录的抽象层,允许开发者在部署时选择不同的日志实现,例如Log4j、Java Util Logging等。 综上所述,这个压缩包包含了一个基本的JPA...

    C# 基于XML实现增删改查 开发架构

    C#程序可以创建一个XML文件,用于存储所有病患的信息,并提供接口来执行增删改查操作。 压缩包中的“BAL”文件夹可能包含了业务逻辑层(Business Access Layer)的代码,这部分代码通常处理数据操作的逻辑,比如...

    C# 通过进程队列实现的企业日志类

    相比Log4net等日志框架,这个类省去了繁琐的XML配置,可能采用更直观的代码方式进行设置,降低了使用门槛,使开发者可以更快地集成到项目中。 6. **代码结构**: 提供的文件`LoggerDemo.aspx`和`LoggerDemo.aspx....

Global site tag (gtag.js) - Google Analytics