mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-07-11 14:00:32 +08:00
git-svn-id: svn://fileserver/activex/AVS/Sources/TeamlabOffice/trunk/ServerComponents@63917 954022d7-b5bf-4e40-9824-e11837661b57
714 lines
18 KiB
C++
714 lines
18 KiB
C++
#include "../include/xmlutils.h"
|
||
#include "./xmllight_private.h"
|
||
#include <list>
|
||
|
||
namespace XmlUtils
|
||
{
|
||
CXmlNodeBase::CXmlNodeBase()
|
||
{
|
||
m_pDocument = NULL;
|
||
m_sText = L"";
|
||
m_sName = L"";
|
||
}
|
||
CXmlNodeBase::~CXmlNodeBase()
|
||
{
|
||
if (NULL != m_pDocument)
|
||
m_pDocument->Release();
|
||
|
||
int nCount = (int)m_nodes.size();
|
||
for (int i = 0; i < nCount; ++i)
|
||
{
|
||
CXmlNodeBase* pNode = m_nodes[i];
|
||
if (NULL != pNode)
|
||
pNode->Release();
|
||
}
|
||
}
|
||
|
||
void CXmlNodeBase::AddRefDoc()
|
||
{
|
||
if (NULL != m_pDocument)
|
||
m_pDocument->AddRef();
|
||
}
|
||
void CXmlNodeBase::ReleaseDoc()
|
||
{
|
||
if (NULL != m_pDocument)
|
||
m_pDocument->Release();
|
||
}
|
||
|
||
std::wstring CXmlNodeBase::GetXml()
|
||
{
|
||
NSStringUtils::CStringBuilder oWriter;
|
||
GetXml(oWriter);
|
||
return oWriter.GetData();
|
||
}
|
||
void CXmlNodeBase::GetXml(NSStringUtils::CStringBuilder& oWriter)
|
||
{
|
||
oWriter.WriteString(L"<", 1);
|
||
oWriter.WriteEncodeXmlString(m_sName.c_str());
|
||
|
||
std::map<std::string, std::string>::iterator p;
|
||
for (p = m_attributes.begin(); p != m_attributes.end(); ++p)
|
||
{
|
||
oWriter.WriteString(L" ", 1);
|
||
oWriter.WriteEncodeXmlString(NSFile::CUtf8Converter::GetUnicodeFromCharPtr(p->first.c_str(), p->first.length(), true).c_str());
|
||
oWriter.WriteString(L"=\"", 2);
|
||
oWriter.WriteEncodeXmlString(NSFile::CUtf8Converter::GetUnicodeFromCharPtr(p->second.c_str(), p->second.length(), true).c_str());
|
||
oWriter.WriteString(L"\"", 1);
|
||
}
|
||
|
||
oWriter.WriteString(L">", 1);
|
||
|
||
int nCount = m_nodes.size();
|
||
for (int i = 0; i < nCount; ++i)
|
||
{
|
||
m_nodes[i]->GetXml(oWriter);
|
||
}
|
||
|
||
oWriter.WriteEncodeXmlString(m_sText.c_str());
|
||
|
||
oWriter.WriteString(L"</", 2);
|
||
oWriter.WriteEncodeXmlString(m_sName.c_str());
|
||
oWriter.WriteString(L">", 1);
|
||
}
|
||
}
|
||
|
||
namespace XmlUtils
|
||
{
|
||
CXmlNodes::CXmlNodes() : m_nodes()
|
||
{
|
||
}
|
||
bool CXmlNodes::IsValid()
|
||
{
|
||
return true;
|
||
}
|
||
int CXmlNodes::GetCount()
|
||
{
|
||
return (int)m_nodes.size();
|
||
}
|
||
bool CXmlNodes::GetAt(int nIndex, CXmlNode& oXmlNode)
|
||
{
|
||
if (nIndex < 0 || nIndex >= GetCount())
|
||
return false;
|
||
|
||
oXmlNode = m_nodes[nIndex];
|
||
return true;
|
||
}
|
||
}
|
||
|
||
namespace XmlUtils
|
||
{
|
||
class CXmlDOMDocument : public IXmlDOMDocument, public CXmlLiteReader_Private
|
||
{
|
||
public:
|
||
CXmlNodeBase* m_pNode;
|
||
|
||
private:
|
||
CXmlNodeBase* m_pCurrentNode;
|
||
std::list<CXmlNodeBase*> m_list;
|
||
|
||
public:
|
||
CXmlDOMDocument() : IXmlDOMDocument()
|
||
{
|
||
m_pNode = NULL;
|
||
m_pCurrentNode = NULL;
|
||
}
|
||
virtual ~CXmlDOMDocument()
|
||
{
|
||
}
|
||
|
||
void WriteElement()
|
||
{
|
||
if (NULL == m_pCurrentNode)
|
||
{
|
||
m_pNode = new CXmlNodeBase();
|
||
m_pNode->m_pDocument = this;
|
||
m_pNode->m_pDocument->AddRef();
|
||
|
||
m_pCurrentNode = m_pNode;
|
||
}
|
||
else
|
||
{
|
||
// это m_pCurrentNode
|
||
CXmlNodeBase* pNewBase = new CXmlNodeBase();
|
||
pNewBase->m_pDocument = this;
|
||
pNewBase->m_pDocument->AddRef();
|
||
|
||
m_pCurrentNode->m_nodes.insert(m_pCurrentNode->m_nodes.end(), pNewBase);
|
||
m_pCurrentNode = pNewBase;
|
||
}
|
||
|
||
m_pCurrentNode->m_sName = GetName();
|
||
m_list.push_back(m_pCurrentNode);
|
||
|
||
if (GetAttributesCount() > 0)
|
||
{
|
||
MoveToFirstAttribute();
|
||
std::string sName = GetNameA();
|
||
while (!sName.empty())
|
||
{
|
||
m_pCurrentNode->m_attributes.insert(std::make_pair(sName, GetTextA()));
|
||
|
||
if (!MoveToNextAttribute())
|
||
break;
|
||
|
||
sName = GetNameA();
|
||
}
|
||
MoveToElement();
|
||
}
|
||
if (IsEmptyNode())
|
||
{
|
||
m_list.pop_back();
|
||
|
||
if (0 != m_list.size())
|
||
{
|
||
std::list<CXmlNodeBase*>::iterator iter = m_list.end();
|
||
--iter;
|
||
m_pCurrentNode = *iter;
|
||
}
|
||
else
|
||
{
|
||
m_pCurrentNode = m_pNode;
|
||
}
|
||
}
|
||
}
|
||
|
||
void Parse()
|
||
{
|
||
ReadNextNode();
|
||
|
||
WriteElement();
|
||
|
||
int nDepth = GetDepth();
|
||
if (!IsEmptyElement())
|
||
{
|
||
XmlNodeType eNodeType = XmlNodeType_None;
|
||
|
||
int nCurDepth = -1;
|
||
// У закрывающего тэга глубина на 1 больше, чем у открывающего
|
||
while (true)
|
||
{
|
||
if (1 != xmlTextReaderRead(reader))
|
||
break;
|
||
|
||
int nTempType = xmlTextReaderNodeType(reader);
|
||
if (-1 == nTempType)
|
||
break;
|
||
eNodeType = (XmlNodeType)nTempType;
|
||
|
||
nCurDepth = GetDepth();
|
||
if (eNodeType == XmlNodeType_Text || eNodeType == XmlNodeType_Whitespace || eNodeType == XmlNodeType_SIGNIFICANT_WHITESPACE)
|
||
m_pCurrentNode->m_sText += GetText();
|
||
else if (eNodeType == XmlNodeType_Element)
|
||
WriteElement();
|
||
else if (eNodeType == XmlNodeType_EndElement)
|
||
{
|
||
m_list.pop_back();
|
||
|
||
if (0 != m_list.size())
|
||
{
|
||
std::list<CXmlNodeBase*>::iterator iter = m_list.end();
|
||
--iter;
|
||
m_pCurrentNode = *iter;
|
||
}
|
||
else
|
||
{
|
||
m_pCurrentNode = m_pNode;
|
||
}
|
||
}
|
||
|
||
nCurDepth = GetDepth();
|
||
if (nCurDepth < nDepth)
|
||
break;
|
||
|
||
if (XmlNodeType_EndElement == eNodeType && nCurDepth == nDepth)
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
};
|
||
}
|
||
|
||
namespace XmlUtils
|
||
{
|
||
CXmlNode::CXmlNode()
|
||
{
|
||
m_pBase = NULL;
|
||
}
|
||
CXmlNode::CXmlNode(const CXmlNode& oSrc)
|
||
{
|
||
m_pBase = NULL;
|
||
SetBase(oSrc.m_pBase);
|
||
}
|
||
CXmlNode::~CXmlNode()
|
||
{
|
||
Clear();
|
||
}
|
||
|
||
bool CXmlNode::FromXmlFile(const wchar_t* sFile, bool bRemoveRootNode)
|
||
{
|
||
return FromXmlFile(std::wstring(sFile), bRemoveRootNode);
|
||
}
|
||
bool CXmlNode::FromXmlFile(const std::wstring& sFile, bool bRemoveRootNode)
|
||
{
|
||
//ignore bRemoveRootNode
|
||
CXmlDOMDocument* m_pDocument = new CXmlDOMDocument();
|
||
bool bRes = m_pDocument->FromFile(sFile);
|
||
|
||
if (false == bRes)
|
||
{
|
||
delete m_pDocument;
|
||
return false;
|
||
}
|
||
|
||
m_pDocument->Parse();
|
||
|
||
if (NULL == m_pDocument->m_pNode)
|
||
{
|
||
delete m_pDocument;
|
||
return false;
|
||
}
|
||
//присваиваем m_pBase без AddRef, чтобы при удалении CXmlNode начался удаляться m_pBase(после конструктора RefCount==1, а если сделать AddRef то не удалится)
|
||
m_pBase = m_pDocument->m_pNode;
|
||
//после Parse все Node из m_pDocument сделали ему AddRef, поэтому можем вызвать Release(потому что напрямую нигде его не используем), а окончательно он удалится после удаления всех Node
|
||
m_pDocument->Release();
|
||
|
||
return true;
|
||
}
|
||
|
||
bool CXmlNode::FromXmlStringA(const std::string& sString)
|
||
{
|
||
CXmlDOMDocument* m_pDocument = new CXmlDOMDocument();
|
||
bool bRes = m_pDocument->FromStringA(sString);
|
||
|
||
if (false == bRes)
|
||
{
|
||
delete m_pDocument;
|
||
return false;
|
||
}
|
||
|
||
m_pDocument->Parse();
|
||
|
||
if (NULL == m_pDocument->m_pNode)
|
||
{
|
||
delete m_pDocument;
|
||
return false;
|
||
}
|
||
//присваиваем m_pBase без AddRef, чтобы при удалении CXmlNode начался удаляться m_pBase(после конструктора RefCount==1, а если сделать AddRef то не удалится)
|
||
m_pBase = m_pDocument->m_pNode;
|
||
//после Parse все Node из m_pDocument сделали ему AddRef, поэтому можем вызвать Release(потому что напрямую нигде его не используем), а окончательно он удалится после удаления всех Node
|
||
m_pDocument->Release();
|
||
return true;
|
||
}
|
||
bool CXmlNode::FromXmlString(const wchar_t* sString)
|
||
{
|
||
return FromXmlString(std::wstring(sString));
|
||
}
|
||
bool CXmlNode::FromXmlString(const std::wstring& sString)
|
||
{
|
||
return FromXmlStringA(NSFile::CUtf8Converter::GetUtf8StringFromUnicode2(sString.c_str(), (LONG)sString.length()));
|
||
}
|
||
|
||
bool CXmlNode::IsValid() const
|
||
{
|
||
return (NULL != m_pBase);
|
||
}
|
||
void CXmlNode::Clear()
|
||
{
|
||
this->SetBase(NULL);
|
||
}
|
||
std::wstring CXmlNode::GetName()
|
||
{
|
||
return (IsValid() ? m_pBase->m_sName : L"");
|
||
}
|
||
std::wstring CXmlNode::GetText()
|
||
{
|
||
return (IsValid() ? m_pBase->m_sText : L"");
|
||
}
|
||
bool CXmlNode::GetTextIfExist(std::wstring& sOutput)
|
||
{
|
||
bool bRes = false;
|
||
if (IsValid() && !m_pBase->m_sText.empty())
|
||
{
|
||
sOutput = m_pBase->m_sText;
|
||
bRes = true;
|
||
}
|
||
return bRes;
|
||
}
|
||
std::wstring CXmlNode::GetTextExt(const std::wstring& strDefaultValue)
|
||
{
|
||
//todo xml:space preserve
|
||
std::wstring sRes;
|
||
if (!GetTextIfExist(sRes))
|
||
sRes = strDefaultValue;
|
||
return sRes;
|
||
}
|
||
std::wstring CXmlNode::GetXml(const std::wstring& strDefaultValue)
|
||
{
|
||
return private_GetXmlFast(strDefaultValue);
|
||
}
|
||
|
||
std::wstring CXmlNode::ReadAttributeBase(const wchar_t* bstrName)
|
||
{
|
||
return GetAttribute(std::wstring(bstrName));
|
||
}
|
||
std::wstring CXmlNode::ReadAttribute(const std::wstring& strAttibuteName)
|
||
{
|
||
return GetAttribute(std::wstring(strAttibuteName));
|
||
}
|
||
|
||
std::string CXmlNode::GetAttributeA(const std::string& sName, const std::string& _default)
|
||
{
|
||
if (!IsValid())
|
||
return _default;
|
||
|
||
std::map<std::string, std::string>::const_iterator pFind = m_pBase->m_attributes.find(sName);
|
||
if (pFind == m_pBase->m_attributes.end())
|
||
return _default;
|
||
|
||
return pFind->second;
|
||
}
|
||
std::string CXmlNode::GetAttributeA(const std::wstring& sName, const std::string& _default)
|
||
{
|
||
return GetAttributeA(NSFile::CUtf8Converter::GetUtf8StringFromUnicode2(sName.c_str(), (LONG)sName.length()));
|
||
}
|
||
|
||
std::wstring CXmlNode::GetAttribute(const std::string& sName, const std::wstring& _default)
|
||
{
|
||
if (!IsValid())
|
||
return _default;
|
||
|
||
std::map<std::string, std::string>::const_iterator pFind = m_pBase->m_attributes.find(sName);
|
||
if (pFind == m_pBase->m_attributes.end())
|
||
return _default;
|
||
|
||
return NSFile::CUtf8Converter::GetUnicodeFromCharPtr(pFind->second);
|
||
}
|
||
std::wstring CXmlNode::GetAttribute(const std::wstring& sName, const std::wstring& _default)
|
||
{
|
||
if (!IsValid())
|
||
return _default;
|
||
|
||
std::map<std::string, std::string>::const_iterator pFind = m_pBase->m_attributes.find(U_TO_UTF8(sName));
|
||
if (pFind == m_pBase->m_attributes.end())
|
||
return _default;
|
||
|
||
return NSFile::CUtf8Converter::GetUnicodeFromCharPtr(pFind->second);
|
||
}
|
||
std::wstring CXmlNode::GetAttribute(const wchar_t* sName, const std::wstring& _default)
|
||
{
|
||
return GetAttribute(std::wstring(sName), _default);
|
||
}
|
||
|
||
std::wstring CXmlNode::GetAttributeBase(const wchar_t* strAttributeName, const std::wstring& strDefaultValue)
|
||
{
|
||
return GetAttribute(std::wstring(strAttributeName), strDefaultValue);
|
||
}
|
||
bool CXmlNode::GetAttributeIfExist(const std::wstring& sName, std::wstring& sOutput)
|
||
{
|
||
bool bRes = false;
|
||
if (IsValid())
|
||
{
|
||
std::map<std::string, std::string>::const_iterator pFind = m_pBase->m_attributes.find(U_TO_UTF8(sName));
|
||
|
||
if (pFind != m_pBase->m_attributes.end())
|
||
{
|
||
sOutput = NSFile::CUtf8Converter::GetUnicodeFromCharPtr(pFind->second);
|
||
bRes = true;
|
||
}
|
||
}
|
||
return bRes;
|
||
}
|
||
|
||
int CXmlNode::GetAttributeInt(const std::string& sName, const int& _default)
|
||
{
|
||
if (!IsValid())
|
||
return _default;
|
||
|
||
std::map<std::string, std::string>::const_iterator pFind = m_pBase->m_attributes.find(sName);
|
||
|
||
if (pFind == m_pBase->m_attributes.end())
|
||
return _default;
|
||
|
||
if (0 == pFind->second.length())
|
||
return _default;
|
||
|
||
return atoi(pFind->second.c_str());
|
||
}
|
||
int CXmlNode::GetAttributeInt(const std::wstring& sName, const int& _default)
|
||
{
|
||
if (!IsValid())
|
||
return _default;
|
||
|
||
std::map<std::string, std::string>::const_iterator pFind = m_pBase->m_attributes.find(U_TO_UTF8(sName));
|
||
|
||
if (pFind == m_pBase->m_attributes.end())
|
||
return _default;
|
||
|
||
if (0 == pFind->second.length())
|
||
return _default;
|
||
|
||
return atoi(pFind->second.c_str());
|
||
}
|
||
int CXmlNode::ReadAttributeInt(const std::wstring& str, const int& _default)
|
||
{
|
||
return GetAttributeInt(str, _default);
|
||
}
|
||
|
||
double CXmlNode::GetAttributeDouble(const std::string& sName, const double& _default)
|
||
{
|
||
if (!IsValid())
|
||
return _default;
|
||
|
||
std::map<std::string, std::string>::const_iterator pFind = m_pBase->m_attributes.find(sName);
|
||
|
||
if (pFind == m_pBase->m_attributes.end())
|
||
return _default;
|
||
|
||
if (0 == pFind->second.length())
|
||
return _default;
|
||
|
||
return atof(pFind->second.c_str());
|
||
}
|
||
double CXmlNode::GetAttributeDouble(const std::wstring& sName, const double& _default)
|
||
{
|
||
if (!IsValid())
|
||
return _default;
|
||
|
||
std::map<std::string, std::string>::const_iterator pFind = m_pBase->m_attributes.find(U_TO_UTF8(sName));
|
||
|
||
if (pFind == m_pBase->m_attributes.end())
|
||
return _default;
|
||
|
||
if (0 == pFind->second.length())
|
||
return _default;
|
||
|
||
return atof(pFind->second.c_str());
|
||
}
|
||
double CXmlNode::ReadAttributeDouble(const std::wstring& str, const double& _default)
|
||
{
|
||
return GetAttributeDouble(str, _default);
|
||
}
|
||
|
||
std::wstring CXmlNode::ReadNodeTextBase(const wchar_t* bsName)
|
||
{
|
||
return ReadNodeText(std::wstring(bsName));
|
||
}
|
||
|
||
std::wstring CXmlNode::ReadNodeText(const std::wstring& strName)
|
||
{
|
||
return ReadValueString(strName);
|
||
}
|
||
std::wstring CXmlNode::ReadValueString(const std::wstring& sName, const std::wstring& nDef)
|
||
{
|
||
CXmlNode oTemp;
|
||
if (GetNode(sName, oTemp))
|
||
return oTemp.GetText();
|
||
return L"";
|
||
}
|
||
int CXmlNode::ReadValueInt(const std::wstring& str, const int& nDef)
|
||
{
|
||
int nRes = nDef;
|
||
CXmlNode oTemp;
|
||
if (GetNode(str, oTemp))
|
||
{
|
||
std::wstring sText;
|
||
if (oTemp.GetTextIfExist(sText))
|
||
nRes = std::stoi(str);
|
||
}
|
||
return nRes;
|
||
}
|
||
|
||
std::wstring CXmlNode::GetAttributeOrValue(const std::wstring& strAttributeName, const std::wstring& strDefaultValue)
|
||
{
|
||
std::wstring sRes;
|
||
if (!GetAttributeIfExist(strAttributeName, sRes))
|
||
{
|
||
if (!GetTextIfExist(sRes))
|
||
sRes = strDefaultValue;
|
||
}
|
||
return sRes;
|
||
}
|
||
|
||
CXmlNode CXmlNode::ReadNode(const wchar_t* strNodeName)
|
||
{
|
||
CXmlNode oNode;
|
||
GetNode(std::wstring(strNodeName), oNode);
|
||
return oNode;
|
||
}
|
||
CXmlNode CXmlNode::ReadNode(const std::wstring& strNodeName)
|
||
{
|
||
CXmlNode oNode;
|
||
GetNode(strNodeName, oNode);
|
||
return oNode;
|
||
}
|
||
CXmlNode CXmlNode::ReadNodeNoNS(const std::wstring& strNodeName)
|
||
{
|
||
CXmlNode node;
|
||
if (IsValid())
|
||
{
|
||
int nCount = (int)m_pBase->m_nodes.size();
|
||
for (int i = 0; i < nCount; ++i)
|
||
{
|
||
if (strNodeName == GetNameNoNS(m_pBase->m_nodes[i]->m_sName))
|
||
{
|
||
CXmlNodeBase* pBase = m_pBase->m_nodes[i];
|
||
node.SetBase(pBase);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
return node;
|
||
}
|
||
CXmlNodes CXmlNode::ReadNodesNoNS(const std::wstring& sName)
|
||
{
|
||
CXmlNodes oNodes;
|
||
if (IsValid())
|
||
{
|
||
bool bGetAll = false;
|
||
if (L"*" == sName)
|
||
bGetAll = true;
|
||
int nCount = (int)m_pBase->m_nodes.size();
|
||
for (int i = 0; i < nCount; ++i)
|
||
{
|
||
if (bGetAll || sName == GetNameNoNS(m_pBase->m_nodes[i]->m_sName))
|
||
{
|
||
CXmlNode oNode;
|
||
CXmlNodeBase* pBase = m_pBase->m_nodes[i];
|
||
oNode.SetBase(pBase);
|
||
oNodes.m_nodes.insert(oNodes.m_nodes.end(), oNode);
|
||
}
|
||
}
|
||
}
|
||
|
||
return oNodes;
|
||
}
|
||
|
||
CXmlNode CXmlNode::GetNode(const std::wstring& sName)
|
||
{
|
||
CXmlNode oNode;
|
||
GetNode(sName, oNode);
|
||
return oNode;
|
||
}
|
||
CXmlNodes CXmlNode::GetNodes(const std::wstring& sName)
|
||
{
|
||
CXmlNodes oNodes;
|
||
if (IsValid())
|
||
{
|
||
bool bGetAll = false;
|
||
if (L"*" == sName)
|
||
bGetAll = true;
|
||
int nCount = (int)m_pBase->m_nodes.size();
|
||
for (int i = 0; i < nCount; ++i)
|
||
{
|
||
if (bGetAll || sName == m_pBase->m_nodes[i]->m_sName)
|
||
{
|
||
CXmlNode oNode;
|
||
CXmlNodeBase* pBase = m_pBase->m_nodes[i];
|
||
oNode.SetBase(pBase);
|
||
oNodes.m_nodes.insert(oNodes.m_nodes.end(), oNode);
|
||
}
|
||
}
|
||
}
|
||
|
||
return oNodes;
|
||
}
|
||
bool CXmlNode::GetChilds(CXmlNodes& oXmlNodes)
|
||
{
|
||
bool bRes = false;
|
||
if (IsValid())
|
||
{
|
||
int nCount = (int)m_pBase->m_nodes.size();
|
||
if (nCount > 0)
|
||
{
|
||
bRes = true;
|
||
for (int i = 0; i < nCount; ++i)
|
||
{
|
||
CXmlNode oNode;
|
||
CXmlNodeBase* pBase = m_pBase->m_nodes[i];
|
||
oNode.SetBase(pBase);
|
||
oXmlNodes.m_nodes.insert(oXmlNodes.m_nodes.end(), oNode);
|
||
}
|
||
}
|
||
}
|
||
return bRes;
|
||
}
|
||
|
||
bool CXmlNode::GetNode(const std::wstring& sName, CXmlNode& oNode)
|
||
{
|
||
bool bRes = false;
|
||
if (IsValid())
|
||
{
|
||
int nCount = (int)m_pBase->m_nodes.size();
|
||
for (int i = 0; i < nCount; ++i)
|
||
{
|
||
if (sName == m_pBase->m_nodes[i]->m_sName)
|
||
{
|
||
CXmlNodeBase* pBase = m_pBase->m_nodes[i];
|
||
oNode.SetBase(pBase);
|
||
bRes = true;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
return bRes;
|
||
}
|
||
bool CXmlNode::GetNodes(const std::wstring& sName, CXmlNodes& oNodes)
|
||
{
|
||
oNodes = GetNodes(sName);
|
||
return (0 != oNodes.GetCount());
|
||
}
|
||
|
||
CXmlNode& CXmlNode::operator=(const CXmlNode& oSrc)
|
||
{
|
||
this->SetBase(oSrc.m_pBase);
|
||
return *this;
|
||
}
|
||
|
||
std::wstring CXmlNode::private_GetXml()
|
||
{
|
||
return private_GetXml(L"");
|
||
}
|
||
std::wstring CXmlNode::private_GetXml(const std::wstring& strDefaultValue)
|
||
{
|
||
if (NULL == m_pBase)
|
||
return strDefaultValue;
|
||
return m_pBase->GetXml();
|
||
}
|
||
std::wstring CXmlNode::private_GetXmlFast()
|
||
{
|
||
return private_GetXmlFast(L"");
|
||
}
|
||
std::wstring CXmlNode::private_GetXmlFast(const std::wstring& strDefaultValue)
|
||
{
|
||
if (NULL == m_pBase)
|
||
return strDefaultValue;
|
||
NSStringUtils::CStringBuilder oWriter;
|
||
m_pBase->GetXml(oWriter);
|
||
return oWriter.GetData();
|
||
}
|
||
|
||
void CXmlNode::SetBase(CXmlNodeBase* pBase)
|
||
{
|
||
CXmlNodeBase* pBaseOld = m_pBase;
|
||
m_pBase = pBase;
|
||
if (NULL != m_pBase)
|
||
m_pBase->AddRef();
|
||
if (NULL != pBaseOld)
|
||
pBaseOld->Release();
|
||
}
|
||
std::wstring CXmlNode::GetNamespace(const std::wstring& strNodeName)
|
||
{
|
||
int nFind = strNodeName.find(wchar_t(':'));
|
||
if (-1 == nFind)
|
||
return L"";
|
||
return strNodeName.substr(0, nFind);
|
||
}
|
||
std::wstring CXmlNode::GetNameNoNS(const std::wstring& strNodeName)
|
||
{
|
||
int nFind = strNodeName.find(wchar_t(':'));
|
||
if (-1 == nFind)
|
||
return strNodeName;
|
||
return strNodeName.substr(nFind + 1);
|
||
}
|
||
}
|