#pragma once
#import "MSXML3.dll" named_guids
#include <string>
class xmldocument;
class xmlnode;
class xmlnodelist;
class xmldocument
{
public:
/// Constructor
xmldocument()
{
CoInitialize(NULL);
m_xmldoc.CreateInstance(MSXML2::CLSID_DOMDocument30);
MSXML2::IXMLDOMDocument2Ptr doc = m_xmldoc;
doc->setProperty("SelectionLanguage","XPath");
}
/// Loading
bool load(std::string url)
{
if (m_xmldoc!=NULL)
{
_variant_t v(url.c_str());
m_xmldoc->put_async(VARIANT_FALSE);
VARIANT_BOOL success = m_xmldoc->load(v);
return success == VARIANT_TRUE;
}
return false;
}
bool load(std::wstring url)
{
if (m_xmldoc!=NULL)
{
_variant_t v(url.c_str());
m_xmldoc->put_async(VARIANT_FALSE);
VARIANT_BOOL success = m_xmldoc->load(v);
return success == VARIANT_TRUE;
}
return false;
}
bool save(std::string url)
{
_variant_t v(url.c_str());
return m_xmldoc->save(v) == S_OK;
}
bool save(std::wstring url)
{
_variant_t v(url.c_str());
return m_xmldoc->save(v) == S_OK;
}
// Access operators
MSXML2::IXMLDOMNodePtr operator[](int index)
{
if (m_xmldoc!=NULL) return m_xmldoc->childNodes->item[index];
else return NULL;
}
MSXML2::IXMLDOMNodePtr operator[](std::string name)
{
if (m_xmldoc!=NULL) return m_xmldoc->selectSingleNode(name.c_str());
else return NULL;
}
MSXML2::IXMLDOMNodePtr operator[](std::wstring name)
{
if (m_xmldoc!=NULL) return m_xmldoc->selectSingleNode(name.c_str());
else return NULL;
}
MSXML2::IXMLDOMNodeListPtr operator()(std::string xpath)
{
if (m_xmldoc!=NULL) return m_xmldoc->selectNodes(xpath.c_str());
else return NULL;
}
MSXML2::IXMLDOMNodeListPtr operator()(std::wstring xpath)
{
if (m_xmldoc!=NULL) return m_xmldoc->selectNodes(xpath.c_str());
else return NULL;
}
MSXML2::IXMLDOMNodeListPtr children()
{
if (m_xmldoc!=NULL) return m_xmldoc->childNodes;
else return NULL;
}
/// Cast operators / extractors
operator MSXML2::IXMLDOMNodePtr()
{
if (m_xmldoc!=NULL) return m_xmldoc->documentElement;
else return NULL;
}
private:
MSXML2::IXMLDOMDocumentPtr m_xmldoc;
};
class xmlnode
{
public:
struct xmlvalue
{
_bstr_t value;
xmlvalue() {}
xmlvalue(_bstr_t val) { value = val; }
operator std::string()
{
return (const char*)value;
}
operator std::wstring()
{
return (const wchar_t*)value;
}
operator bool()
{
if (_stricmp(value, "yes") == 0 || _stricmp(value, "true") == 0 || _stricmp(value, "1") == 0)
return true;
else return false;
return false;
}
operator short()
{
return atoi(value);
}
operator int()
{
return atoi(value);
}
operator long()
{
return atol(value);
}
operator unsigned short()
{
return atoi(value);
}
operator unsigned long()
{
return atol(value);
}
operator float()
{
return (float)atof(value);
}
operator double()
{
return atof(value);
}
};
public:
xmlnode(MSXML2::IXMLDOMNodePtr source)
{
m_xmlnode = source;
}
void operator=(MSXML2::IXMLDOMNodePtr source)
{
m_xmlnode = source;
}
xmlnode operator[](int index)
{
if (m_xmlnode!=NULL) return m_xmlnode->childNodes->item[index];
else return NULL;
}
xmlnode operator[](std::string name)
{
if (m_xmlnode!=NULL) return m_xmlnode->selectSingleNode(name.c_str());
else return NULL;
}
xmlnode operator[](std::wstring name)
{
if (m_xmlnode!=NULL) return m_xmlnode->selectSingleNode(name.c_str());
else return NULL;
}
MSXML2::IXMLDOMNodeListPtr operator()(std::string xpath)
{
if (m_xmlnode!=NULL) return m_xmlnode->selectNodes(xpath.c_str());
else return NULL;
}
MSXML2::IXMLDOMNodeListPtr operator()(std::wstring xpath)
{
if (m_xmlnode!=NULL) return m_xmlnode->selectNodes(xpath.c_str());
else return NULL;
}
__declspec(property(get=Getvalue,put=Putvalue))
xmlvalue value;
xmlvalue Getvalue()
{
if (m_xmlnode!=NULL) return xmlvalue(m_xmlnode->text);
return xmlvalue();
}
void Putvalue(xmlvalue newVal)
{
if (m_xmlnode!=NULL) m_xmlnode->text = newVal.value;
}
private:
MSXML2::IXMLDOMNodePtr m_xmlnode;
};
class xmlnodelist
{
public:
xmlnodelist(MSXML2::IXMLDOMNodeListPtr source)
{
m_xmlnodelist = source;
}
void operator=(MSXML2::IXMLDOMNodeListPtr source)
{
m_xmlnodelist = source;
}
int length()
{
if (m_xmlnodelist!=NULL) return m_xmlnodelist->length;
else return 0;
}
xmlnode operator[] (int index)
{
if (m_xmlnodelist!=NULL) return m_xmlnodelist->item[index];
else return NULL;
}
private:
MSXML2::IXMLDOMNodeListPtr m_xmlnodelist;
};
#include "stdafx.h"
#include "xml.h"
int _tmain(int argc, _TCHAR* argv[])
{
xmldocument doc;
doc.load("c:\\inventory.xml");
// Cast to node
xmlnode root(doc);
// Retrievers
xmlnode magazine = doc["magazine"];
magazine = root["magazine"];
xmlnodelist books = doc("book");
books = root("book");
// Iteraring and getting value
for (int i = 0; i < books.length(); i++)
{
std::string firstname = books[i]["author"]["first-name"].value;
std::wstring lastname = books[i]["author"]["last-name"].value;
int price = books[i]["price"].value;
}
doc.save("c:\\inventory.xml");
return 0;
}
Have a question about something in this article? You can receive help directly from the article author. Sign up for a free trial to get started.
Comments (4)
Commented:
Do you think this code is the C++ style?
It's not a complain. It is nice. It is great from the theoretical point of view.
But from the practical point of view, I think, it's better to use C# than overload C++ code with such tricks. Probably, it was not very convinient to debug such code?
It is a good way to "hide" the implementation.
Commented:
Author
Commented:http://msdn.microsoft.com/en-us/library/windows/desktop/ms762271(v=vs.85).aspx
Commented: