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

📄 node.cpp

📁 自动化编译工具代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#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 + -