📄 node.cpp
字号:
#include "stdafx.h"
#include "Node.h"
///////////////////////////////////////////////////////////////////////////////
//
// CNodeException
//
///////////////////////////////////////////////////////////////////////////////
CNodeException::CNodeException(int nCode, const CString& sMessage)
: m_nCode(nCode), m_sMessage(sMessage)
{
}
int CNodeException::GetCode()
{
return m_nCode;
}
CString CNodeException::GetMessage()
{
return m_sMessage;
}
///////////////////////////////////////////////////////////////////////////////
//
// CFragmentCollection
//
///////////////////////////////////////////////////////////////////////////////
MSXML2::IXMLDOMDocument2Ptr CFragmentCollection::GetDocument()
{
if (m_spDocument == NULL)
{
m_spDocument.CreateInstance(__uuidof(MSXML2::DOMDocument40));
m_spDocument->async = VARIANT_FALSE;
m_spDocument->setProperty(_T("NewParser"), true);
}
return m_spDocument;
}
MSXML2::IXMLDOMNodePtr CFragmentCollection::CreateFragment()
{
//return GetDocument()->createDocumentFragment();
TCHAR szNumber[32] = _T("tmp");
_itot(m_nTmpNameCounter++, szNumber + 3, 10);
if (m_spFragment == NULL)
{
m_spFragment = GetDocument()->createDocumentFragment();
}
MSXML2::IXMLDOMNodePtr spNode = GetDocument()->createElement(szNumber);
m_spFragment->appendChild( spNode );
return spNode;
}
void CFragmentCollection::CheckDocumentCounter()
{
if (m_spDocument)
{
m_spDocument->AddRef();
if (m_spDocument->Release() == 1)
{
m_spFragment.Release();
m_spDocument.Release();
}
}
}
MSXML2::IXMLDOMDocument2Ptr CFragmentCollection::m_spDocument = NULL;
MSXML2::IXMLDOMDocumentFragmentPtr CFragmentCollection::m_spFragment = NULL;
int CFragmentCollection::m_nTmpNameCounter = 0;
///////////////////////////////////////////////////////////////////////////////
//
// CNode
//
///////////////////////////////////////////////////////////////////////////////
CNode::CNode()
{
m_spDocument = CFragmentCollection::GetDocument();
m_spNode = CFragmentCollection::CreateFragment();
}
CNode::CNode(CNode& rParentNode, MSXML2::IXMLDOMNodePtr spThisNode)
{
m_spDocument = rParentNode.m_spDocument;
m_spNode = spThisNode;
}
CNode::CNode(MSXML2::IXMLDOMDocument2Ptr& rspDocument)
{
m_spDocument = rspDocument;
m_spNode = rspDocument->documentElement;
}
CNode::~CNode()
{
if ( m_spDocument )
m_spDocument.Release();
CFragmentCollection::CheckDocumentCounter();
}
CString CNode::Transform(const CString& sXSLTFilename)
{
MSXML2::IXMLDOMDocument2Ptr spXSLTDocument;
spXSLTDocument.CreateInstance(__uuidof(MSXML2::DOMDocument40));
spXSLTDocument->async = VARIANT_FALSE;
spXSLTDocument->setProperty(_T("NewParser"), true);
if (!spXSLTDocument->load(_variant_t(sXSLTFilename)))
{
MSXML2::IXMLDOMParseErrorPtr spError = spXSLTDocument->parseError;
throw CNodeException(CNodeException::eError1, (LPCTSTR)spError->reason);
}
return (LPCTSTR)m_spNode->transformNode(spXSLTDocument);
}
void CNode::DeclareNamespace(const CString& sPrefix, const CString& sURI)
{
if (sURI.IsEmpty())
return;
MSXML2::IXMLDOMElementPtr spRootElement = m_spDocument->documentElement;
if (sPrefix.IsEmpty())
spRootElement->setAttribute(_T("xmlns"), (LPCTSTR)sURI);
else
spRootElement->setAttribute((LPCTSTR)(_T("xmlns:") + sPrefix), (LPCTSTR)sURI);
}
MSXML2::IXMLDOMNodePtr CNode::CreateNode(ENodeType eNodeType, const CString& sNamespaceURI, LPCTSTR szName)
{
_variant_t varNodeType(eNodeType == Element ? (short)MSXML2::NODE_ELEMENT : (short)MSXML2::NODE_ATTRIBUTE);
return m_spDocument->createNode(varNodeType, szName, (LPCTSTR)sNamespaceURI);
}
bool CNode::CompareChildName( MSXML2::IXMLDOMNodePtr spChild, const CString& sNamespaceURI, const CString& sName )
{
return
( spChild->baseName == _bstr_t(sName) ) &&
(
( spChild->namespaceURI == _bstr_t(sNamespaceURI) ) ||
( !spChild->namespaceURI && sNamespaceURI.IsEmpty() )
);
}
int CNode::ChildCount(ENodeType eNodeType, const CString& sNamespaceURI, const CString& sName)
{
if (eNodeType == Element)
{
int nCount = 0;
for (MSXML2::IXMLDOMNodePtr spChild = m_spNode->firstChild; spChild; spChild = spChild->nextSibling)
if ( CompareChildName( spChild, sNamespaceURI, sName ) )
nCount++;
return nCount;
}
else // eNodeType == Attribute
{
return m_spNode->attributes->getQualifiedItem((LPCTSTR)sName, (LPCTSTR)sNamespaceURI) ? 1 : 0;
}
}
MSXML2::IXMLDOMNodePtr CNode::AppendChild(ENodeType eNodeType, const CString& sNamespaceURI, const CString& sName, const CString& sValue)
{
if (eNodeType == Element)
{
MSXML2::IXMLDOMElementPtr spElement = CreateNode(Element, sNamespaceURI, sName);
spElement->text = (LPCTSTR)sValue;
m_spNode->appendChild(spElement);
return spElement;
}
else // eNodeType == Attribute
{
MSXML2::IXMLDOMAttributePtr spAttribute = CreateNode(Attribute, sNamespaceURI, sName);
spAttribute->text = (LPCTSTR)sValue;
MSXML2::IXMLDOMNamedNodeMapPtr spNodeMap = m_spNode->attributes;
if (spNodeMap)
spNodeMap->setNamedItem(spAttribute);
else
AfxMessageBox(_T("No access to attributes"));
return spAttribute;
}
}
MSXML2::IXMLDOMNodePtr CNode::AppendChildAttribute(MSXML2::IXMLDOMNodePtr spNode, const CString& sNamespaceURI, const CString& sName, const CString& sValue)
{
MSXML2::IXMLDOMAttributePtr spAttribute = CreateNode(Attribute, sNamespaceURI, sName);
spAttribute->text = (LPCTSTR)sValue;
spNode->attributes->setNamedItem(spAttribute);
return spAttribute;
}
MSXML2::IXMLDOMNodePtr CNode::AppendChildElement(const CString& sNamespaceURI, const CString& sElement, CNode* pNode, MSXML2::IXMLDOMNodePtr spHostNode/* = MSXML2::IXMLDOMNodePtr()*/)
{
MSXML2::IXMLDOMElementPtr spElement = CreateNode(Element, sNamespaceURI, sElement);
while (pNode->m_spNode->firstChild != 0)
{
spElement->appendChild(pNode->m_spNode->removeChild(pNode->m_spNode->firstChild));
}
MSXML2::IXMLDOMNamedNodeMapPtr spAttributeMap = pNode->m_spNode->attributes;
while (spAttributeMap->length > 0)
{
spElement->attributes->setNamedItem(spAttributeMap->removeNamedItem(spAttributeMap->item[0]->nodeName));
}
pNode->m_spNode = spElement;
pNode->m_spDocument = m_spDocument;
if (spHostNode == NULL)
m_spNode->appendChild(spElement);
else
spHostNode->appendChild(spElement);
return spElement;
}
MSXML2::IXMLDOMNodePtr CNode::RemoveChildAt(ENodeType eNodeType, const CString& sNamespaceURI, const CString& sName, int nIndex)
{
if (eNodeType == Element)
{
int nCount = 0;
for (MSXML2::IXMLDOMNodePtr spChild = m_spNode->firstChild; spChild; spChild = spChild->nextSibling)
if ( CompareChildName( spChild, sNamespaceURI, sName ) )
if (nCount++ == nIndex)
return m_spNode->removeChild(spChild);
if (nCount > 0)
throw CNodeException(CNodeException::eError1, _T("Index out of range"));
else
throw CNodeException(CNodeException::eError1, _T("Not found"));
}
else // eNodeType == Attribute
{
return m_spNode->attributes->removeNamedItem((LPCTSTR)sName);
}
}
MSXML2::IXMLDOMNodePtr CNode::ReplaceChildAt(ENodeType eNodeType, const CString& sNamespaceURI, const CString& sName, int nIndex, const CString& sValue)
{
if (eNodeType == Element)
{
int nCount = 0;
for (MSXML2::IXMLDOMNodePtr spChild = m_spNode->firstChild; spChild; spChild = spChild->nextSibling)
if ( CompareChildName( spChild, sNamespaceURI, sName ) )
if (nCount++ == nIndex)
{
MSXML2::IXMLDOMElementPtr spElement = m_spDocument->createElement((LPCTSTR)sName);
spElement->text = (LPCTSTR)sValue;
return m_spNode->replaceChild(spElement, spChild);
}
throw CNodeException(CNodeException::eError1, _T("Not found"));
}
else // eNodeType == Attribute
{
if (nIndex > 0)
throw CNodeException(CNodeException::eError1, _T("Index must be zero"));
MSXML2::IXMLDOMAttributePtr spAttribute = m_spNode->attributes->getQualifiedItem((LPCTSTR)sName, (LPCTSTR)sNamespaceURI);
if (spAttribute)
{
spAttribute->text = (LPCTSTR)sValue;
return spAttribute;
}
else
throw CNodeException(CNodeException::eError1, _T("Not found"));
}
}
MSXML2::IXMLDOMNodePtr CNode::GetChildAt(ENodeType eNodeType, const CString& sNamespaceURI, const CString& sName, int nIndex)
{
if (eNodeType == Element)
{
int nCount = 0;
for (MSXML2::IXMLDOMNodePtr spChild = m_spNode->firstChild; spChild; spChild = spChild->nextSibling)
if ( CompareChildName( spChild, sNamespaceURI, sName ) )
if (nCount++ == nIndex)
return spChild;
if (nCount > 0)
throw CNodeException(CNodeException::eError1, _T("Index out of range"));
else
throw CNodeException(CNodeException::eError1, _T("Not found"));
}
else // eNodeType == Attribute
{
if (nIndex > 0)
throw CNodeException(CNodeException::eError1, _T("Index must be zero"));
MSXML2::IXMLDOMNodePtr spAttribute = m_spNode->attributes->getQualifiedItem((LPCTSTR)sName, (LPCTSTR)sNamespaceURI);
if (spAttribute)
return spAttribute;
else
throw CNodeException(CNodeException::eError1, _T("Index out of range"));
}
}
MSXML2::IXMLDOMNodePtr CNode::SetChild(ENodeType eNodeType, const CString& sNamespaceURI, const CString& sName, const CString& sValue)
{
if (ChildCount(eNodeType, sNamespaceURI, sName) == 0)
return AppendChild(eNodeType, sNamespaceURI, sName, sValue);
else
return ReplaceChildAt(eNodeType, sNamespaceURI, sName, 0, sValue);
}
///////////////////////////////////////////////////////////////////////////////
//
// CDoc
//
///////////////////////////////////////////////////////////////////////////////
MSXML2::IXMLDOMDocument2Ptr CDoc::Load(const CString& sFilename)
{
MSXML2::IXMLDOMDocument2Ptr spDocument;
spDocument.CreateInstance(__uuidof(MSXML2::DOMDocument40));
spDocument->async = VARIANT_FALSE;
spDocument->validateOnParse = VARIANT_FALSE;
spDocument->setProperty(_T("NewParser"), true);
if (!spDocument->load(_variant_t(sFilename)))
{
MSXML2::IXMLDOMParseErrorPtr spError = spDocument->parseError;
throw CNodeException(CNodeException::eError1, (LPCTSTR)spError->reason);
}
return spDocument;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -