📄 xmlmanager.cpp
字号:
// XmlManager.cpp: implementation of the CXmlManager class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "ItemBase.h"
#include "XmlManager.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CXmlManager::CXmlManager(CString strVersion, CString strEncoding)
{
CoInitialize(NULL);
m_pXmlDoc.CreateInstance(__uuidof(DOMDocument));
ASSERT(m_pXmlDoc!=NULL);
CString strData=_T("");
strData.Format(_T("version=\"%s\" encoding=\"%s\""), strVersion, strEncoding);
IXMLDOMProcessingInstructionPtr pXMLProc=m_pXmlDoc->createProcessingInstruction(_bstr_t("xml"), _bstr_t(strData));
m_pXmlDoc->appendChild(pXMLProc);
m_pXmlRoot=m_pXmlDoc->createElement(_bstr_t(XML_ROOT_TITLE));
ASSERT(m_pXmlRoot!=NULL);
m_pXmlDoc->appendChild(m_pXmlRoot);
}
CXmlManager::~CXmlManager()
{
m_pXmlRoot = NULL;
m_pXmlDoc = NULL;
CoUninitialize();
}
int CXmlManager::Load(CString strFileName)
{
int nErr=ERROR_NONE;
if (!strFileName.IsEmpty())
{
ASSERT(m_pXmlDoc!=NULL);
_variant_t varXml(strFileName);
_variant_t varOut(true);
varOut = m_pXmlDoc->load(varXml);
if ((bool)varOut)
{
m_pXmlRoot = m_pXmlDoc->documentElement;
}
else
{
nErr = ERROR_XMLMANAGER_LOAD;
Logging2(nErr, DOMAIN_NAME);
}
}
else
{
nErr = ERROR_FUNC_PARAM_INVALID;
}
return nErr;
}
int CXmlManager::SaveAs(CString strFileName)
{
int nErr=ERROR_NONE;
if (!strFileName.IsEmpty())
{
ASSERT(m_pXmlDoc!=NULL);
HRESULT hr=m_pXmlDoc->save(_bstr_t(strFileName));
if (FAILED(hr))
{
nErr = ERROR_XMLMANAGER_SAVEAS;
}
}
else
{
nErr = ERROR_FUNC_PARAM_INVALID;
}
return nErr;
}
int CXmlManager::SetAttr(IXMLDOMElementPtr &pElement, CString strAttrName, CString strAttrValue)
{
int nErr=ERROR_NONE;
if (pElement!=NULL && !strAttrName.IsEmpty())
{
ASSERT(m_pXmlDoc!=NULL);
HRESULT hr=pElement->setAttribute(_bstr_t(strAttrName), _bstr_t(strAttrValue));
if (FAILED(hr))
{
nErr = ERROR_XMLMANAGER_SETATTR;
}
}
else
{
nErr = ERROR_FUNC_PARAM_INVALID;
}
return nErr;
}
int CXmlManager::GetAttrs(const IXMLDOMNodePtr& pNode, CMapStringToString& mapAttr)
{
int nErr=ERROR_NONE;
IXMLDOMElementPtr pElement=pNode;
if (pElement!=NULL)
{
IXMLDOMNamedNodeMapPtr pNamedNodeMap=NULL;
HRESULT hr=pElement->get_attributes(&pNamedNodeMap);
if (SUCCEEDED(hr) && pNamedNodeMap!=NULL)
{
for (long i=0; i<pNamedNodeMap->length; i++)
{
IXMLDOMNodePtr pAttrNode=pNamedNodeMap->item[i];
CString strAttrName=(char*)pAttrNode->nodeName;
CString strAttrValue=(char*)pAttrNode->text;
if (!strAttrName.IsEmpty()) mapAttr[strAttrName] = strAttrValue;
}
}
else
{
nErr = ERROR_XMLMANAGER_GETATTRS;
}
}
else
{
nErr = ERROR_FUNC_PARAM_INVALID;
}
return nErr;
}
IXMLDOMElementPtr CXmlManager::AddElement(CString strElement, CString strValue,
IXMLDOMElementPtr pParentElement)
{
int nErr=ERROR_NONE;
IXMLDOMElementPtr pRet=NULL;
if (!strElement.IsEmpty())
{
ASSERT(m_pXmlDoc!=NULL);
pRet = m_pXmlDoc->createElement(_bstr_t(strElement));
if (pRet!=NULL)
{
pRet->text = _bstr_t(strValue);
IXMLDOMElementPtr& pParent=(pParentElement!=NULL)?pParentElement:m_pXmlRoot;
if (pParent!=NULL)
{
//从后往前获得除元素值外的第一个Text节点
IXMLDOMNodePtr pFirstText=NULL;
IXMLDOMNodePtr pLastChild = pParent->lastChild;
while (pLastChild!=NULL && pLastChild->nodeType==NODE_TEXT)
{
CString strLastChild=(char*)(pLastChild->text);
if (strLastChild.IsEmpty() && pLastChild!=pParent->firstChild ||
strLastChild.Find(XML_ENTER_STRING)>=0)
pFirstText = pLastChild;
pLastChild = pLastChild->previousSibling;
}
_variant_t vFirstText;
V_VT(&vFirstText) = VT_NULL;
if (pFirstText!=NULL) vFirstText = _variant_t((IXMLDOMNode*)pFirstText);
//计算元素的前后缩进值
CString strTextBegin, strTextEnd;
IXMLDOMNodePtr pParentNode=pParent->parentNode;
while (pParentNode!=NULL)
{
if (!strTextBegin.IsEmpty()) strTextEnd += XML_TAB_STRING; //后缩进比前缩进少一个Tab
strTextBegin += XML_TAB_STRING;
pParentNode = pParentNode->parentNode;
}
strTextBegin = XML_ENTER_STRING+strTextBegin;
strTextEnd = XML_ENTER_STRING+strTextEnd;
//插入前缩进
IXMLDOMTextPtr pText1=m_pXmlDoc->createTextNode(_bstr_t(strTextBegin));
pParent->insertBefore(pText1, vFirstText);
//插入元素
pParent->insertBefore(pRet, vFirstText);
//插入后缩进
if (pFirstText==NULL)
{
IXMLDOMTextPtr pText2=m_pXmlDoc->createTextNode(_bstr_t(strTextEnd));
pParent->insertBefore(pText2, vFirstText);
}
}
}
else
{
nErr = ERROR_XMLMANAGER_CREATEELEMENT;
}
}
else
{
nErr = ERROR_FUNC_PARAM_INVALID;
}
return pRet;
}
BOOL CXmlManager::HasChild(const IXMLDOMNodePtr& pNode)
{
BOOL bRet=FALSE;
if (pNode==NULL) return bRet;
IXMLDOMNodeListPtr pSubNodeList=pNode->childNodes;
for (int j=0; j<pSubNodeList->length; j++)
{
IXMLDOMNodePtr pSubNode=pSubNodeList->item[j];
if (pSubNode->nodeType==NODE_ELEMENT
|| pSubNode->nodeType==NODE_ATTRIBUTE)
{
bRet = TRUE;
break;
}
}
return bRet;
}
int CXmlManager::GetNodeToItem(const IXMLDOMNodePtr& pNode, CItemBase& ItemNode)
{
int nErr=ERROR_NONE;
if (pNode!=NULL)
{
//设置节点名和节点值
CString strNodeName=(char*)pNode->nodeName;
ItemNode.SetAttr(XML_ATTR_ITEM_NAME, strNodeName);
// CString strNodeValue=(char*)pNode->text;
// ItemNode.SetAttr(XML_ATTR_ITEM_VALUE, strNodeValue);
//设置节点的属性
CMapStringToString mapAttr;
GetAttrs(pNode, mapAttr);
CString strAttrName, strAttrValue;
for (POSITION pos=mapAttr.GetStartPosition(); pos!=NULL;)
{
mapAttr.GetNextAssoc(pos, strAttrName, strAttrValue);
ItemNode.SetAttr(strAttrName, strAttrValue);
}
//添加子元素和其它属性
IXMLDOMNodeListPtr pSubNodeList=pNode->childNodes;
for (int j=0; j<pSubNodeList->length; j++)
{
IXMLDOMNodePtr pSubNode=pSubNodeList->item[j];
if (pSubNode->nodeType!=NODE_ELEMENT) continue; //非元素节点跳过
CString strSubNodeName=(char*)pSubNode->nodeName;
CString strSubNodeValue=(char*)pSubNode->text;
//若子节点下仍有子节点则作为子元素添加,否则作为属性添加
if (HasChild(pSubNode))
{
CItemComposite* pItemChild=new CItemComposite();
nErr = GetNodeToItem(pSubNode, *pItemChild);
ItemNode.SetItem(pItemChild);
}
else
{
ItemNode.SetAttr(strSubNodeName, strSubNodeValue);
}
}
}
else
{
nErr = ERROR_FUNC_PARAM_INVALID;
}
return nErr;
}
CItemBase* CXmlManager::GetItem(CString strNodeList)
{
CItemComposite *pRet=new CItemComposite();
GetItem(strNodeList, (CItemBase&)(*pRet));
return pRet;
}
int CXmlManager::GetItem(CString strNodeList, CItemBase& ItemBase)
{
ASSERT(m_pXmlRoot!=NULL);
IXMLDOMNodePtr pNode=NULL;
if (!strNodeList.IsEmpty())
{
pNode = m_pXmlRoot->selectSingleNode(_bstr_t(strNodeList));
}
else
{
pNode = m_pXmlRoot;
}
return GetNodeToItem(pNode, ItemBase);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -