Click here to Skip to main content
15,895,084 members
Articles / Desktop Programming / MFC
Article

C++ XML the easy way!

Rate me:
Please Sign up or sign in to vote.
4.93/5 (68 votes)
10 Jun 2005CPOL5 min read 1.2M   12.4K   143   225
A wrapper for the XML DOM for C++.

Introduction

This article is a successor to my previous article Wrapper class for IXMLDDOMDocument.

The reason that it's published as a different article and not an update is that, it's in no way compatible with the previous one. There are different classes and functions. Also the main difference is that this wrapper works directly with XML pointers without first parsing the XML tree, which leads to a significant speed improvement.

Usage

Add the file "XmlNodeWrapper.cpp" to your project's source files.

Include the file "XmlNodeWrapper.h" in the files you would like to use the wrapper.

#include "XmlNodeWrapper.h"

Reference

CXmlDocumentWrapper

Constructors
  • CXmlDocumentWrapper()

    Creates a new instance of XML document. You have to load a document via Load() or LoadXml()

  • CXmlDocumentWrapper(IXMLDOMDocumentPtr pDoc)

    Attaches the wrapper to the existing document pointer. Will accept as input an IXMLDOMDocumentPtr, IXMLDOMDocument* pointer or IDispatch* pointer.

Methods
  • BOOL IsValid()

    Returns TRUE if the wrapper has a valid pointer to XML document.

  • MSXML2::IXMLDOMDocument* Detach()

    Detaches the wrapper from the XML pointer and returns the pointer. Useful if you passed the external pointer in the constructor and would not like to decrease the reference count on the pointer.

  • MSXML2::IXMLDOMDocument* Clone()

    Creates and returns a clone of the document.

    Suggested usage:

    CXmlDocumentWrapper newDoc(sourceDoc.Clone());
  • BOOL Load(LPCTSTR path)

    Loads a document from a disk file. Returns TRUE on success.

    Usage:

    CXmlDocumentWrapper doc;
    doc.Load("C:\\Test\\xmlSource.xml");
  • BOOL LoadXML(LPCTSTR xml)

    Load the document from a string. Returns TRUE on success.

    Usage:

    CXmlDocumentWrapper doc;
    doc.LoadXML("<Root><SomeObject></SomeObject></Root>");
  • BOOL Save(LPCTSTR path = "")

    Saves the document to a disk file. If the path is an empty string or omitted, the current document URL is used.

  • MSXML2::IXMLDOMNode* AsNode()

    Returns the document root element as XML node.

    Usage:

    CXmlNodeWrapper xmlNode(xmlDoc.AsNode());
  • CString GetXML()

    Returns the current XML loaded in the document as a CString.

  • CString GetUrl()

    Returns the current document URL. Note: The URL is updated every time you use Load() or Save() functions.

CXmlNodeWrapper

Constructors
  • CXmlNodeWrapper()

    Creates an empty Node wrapper. You have to use operator = or Attach() on this node.

  • CXmlNodeWrapper(MSXML2::IXMLDOMNodePtr pNode,BOOL bAutoRelease = TRUE)

    Creates a wrapper from XMl pointer to existing XML node. Will accept IXMLDOMNodePtr, IXMLDOMNode* or IDispatch* pointer. If the bAutoRelease parameter is FALSE, Detach() will be called in the destructor.

  • void operator=(MSXML2::IXMLDOMNodePtr pNode)

    Same as the above.

Methods
  • BOOL IsValid()

    Returns TRUE if the XML pointer in the wrapper is valid.

  • void SetValue(LPCTSTR valueName,LPCTSTR value)
  • void SetValue(LPCTSTR valueName,int value)
  • void SetValue(LPCTSTR valueName,short value)
  • void SetValue(LPCTSTR valueName,double value)
  • void SetValue(LPCTSTR valueName,float value)
  • void SetValue(LPCTSTR valueName,bool value)

    Sets a value for an attribute. If the attribute exists it's value is updated, otherwise a new attribute will be created.

  • CString GetValue(LPCTSTR valueName)

    Returns a value of an attribute as a CString. If the attribute does not exists, an empty string will be returned.

  • MSXML2::IXMLDOMNode* GetPrevSibling()
  • MSXML2::IXMLDOMNode* GetNextSibling()

    Gets the next or previous sibling of this node. If no such exists NULL will be returned.

    Usage:

    CXmlNodeWrapper prevNode(theNode.GetPrevSibling());
    CXmlNodeWrapper nextNode(theNode.GetNextSibling());
    if (prevNode.IsValid())
    {
          // Do things
    }
    else if (nextNode.IsValid())
    {
         // Do things
    }
  • MSXML2::IXMLDOMNode* GetNode(LPCTSTR nodeName)
  • MSXML2::IXMLDOMNode* GetNode(int nodeIndex)

    Returns a child node of this node by index or by name. If no node is found, NULL will be returned. When searching by name only the first matching node will be returned.

    Usage:

    CXmlNodeWrapper childNode(theNode.GetNode(0));
    if (!childNode.IsValid())
    {
         childNode = theNode.GetNode("MyChild");
         // Do things
    }
  • MSXML2::IXMLDOMNode* FindNode(LPCTSTR searchString)

    Returns a single node by evaluating an XSL search pattern (A wrapper for selectSingleNode function).

    Usage:

    //Finds the node with the name "Object"
    // who's "Type" attribute equals "Simple":
    CXmlNodeWrapper resultNode(
                 theNode.FindNode("//Object[@Type='Simple']"));
  • MSXML2::IXMLDOMNodeList* FindNodes(LPCTSTR searchStr)

    Returns a list of nodes by evaluating an XSL search pattern (A wrapper for selectNodes function).

    Usage:

    //Finds all the nodes with the name "Object" 
    //who's "Type" attribute equals "Simple":
    CXmlNodeListWrapper nodeList(
           theNode.FindNodes("//Object[@Type='Simple']"));
  • long NumNodes()

    Returns the number of child nodes.

  • MSXML2::IXMLDOMNode* Parent()

    Return a parent node of this node or NULL if none.

    Usage:

    CXmlNodeWrapper parentNode(theNode.Parent());
  • CString Name();

    Returns the name of the node.

  • CString GetText()

    Returns the text contents of the node.

  • void SetText(LPCTSTR text)

    Sets the text contents of the node.

  • MSXML2::IXMLDOMDocument* ParentDocument()

    Returns the document that this node belongs to or NULL if not applicable.

    Usage:

    CXmlDocumentWrapper xmlDoc(theNode.ParentDocument());
  • MSXML2::IXMLDOMNode* Interface()

    Returns the raw interface pointer, useful to invoke some of the methods not provided by the wrapper or to pass the interface to some other functions without detaching from the wrapper.

  • MSXML2::IXMLDOMNode* Detach()

    Detaches from the XML pointer without calling Release() on it and returns the pointer.

  • CString GetXML()

    Returns the XML contents of the node as CString.

  • MSXML2::IXMLDOMNode* InsertNode(int index,LPCTSTR nodeName)

    Creates a new XML node with the given name and inserts it as a child of this node. Use index=0 to insert as a first child and index=NumNodes() to insert as the last. Returns a pointer to the new node.

    Usage:

    CXmlNodeWrapper newChild(
            theNode.InsertNode(theNode.NumNodes(),"MyNewChild");
    newChild.SetValue("SomeValue","Undefined");
  • MSXML2::IXMLDOMNode* InsertNode(int index,MSXML2::IXMLDOMNodePtr pNode)

    Same as above. Only the new child is not created but accepts a pre-existing pointer to a node.

    Usage:

    // Create a copy of a document 
    //and insert as a child into existing node
    CXmlDocumentWrapper doc;
    doc.Load("C:\\Temp\\xmlSource.xml);
    CXmlNodeWrapper sourceNode(doc.AsNode());
    CXmlDocumentWrapper cloneDoc(doc.Clone());
    sourceNode.InsertNode(0,cloneDoc.AsNode());
  • MSXML2::IXMLDOMNode* InsertAfter(MSXML2::IXMLDOMNode* refNode, LPCTSTR nodeName)
  • MSXML2::IXMLDOMNode* InsertBefore(MSXML2::IXMLDOMNode* refNode, LPCTSTR nodeName)

    Create and insert a new child node with the given name before or after the referenced node. Returns the newly created node.

  • MSXML2::IXMLDOMNode* InsertAfter(MSXML2::IXMLDOMNode *refNode, MSXML2::IXMLDOMNode *pNode)

    Insert an existing node after the referenced node. Returns the inserted node.

  • MSXML2::IXMLDOMNode* RemoveNode(MSXML2::IXMLDOMNodePtr pNode)

    Removes the specified node from the child list of this node. Returns a pointer to the removed node.

  • void RemoveNodes(LPCTSTR searchStr)

    Removes nodes from the child list of this node by evaluating XSL pattern. See FindNodes for an example.

  • void ReplaceNode(MSXML2::IXMLDOMNode* pOldNode,MSXML2::IXMLDOMNode* pNewNode)

    Replaces an existing child node with a new node.

CXmlNodeListWrapper

Constructors
  • CXmlNodeListWrapper()

    Creates an empty node list wrapper, you have to use the operator = to initialize it.

  • CXmlNodeListWrapper(MSXML2::IXMLDOMNodeListPtr pList)

    Creates a node list from an existing IXMLDOMNodeList pointer, will accept IXMLDOMNodeListPtr, IXMLDOMNodeList* pointer or IDispatch* pointer. See example in CXmlNodeWrapper::FindNodes().

  • void operator=(MSXML2::IXMLDOMNodeListPtr pList)

    Same as above.

Methods
  • BOOL IsValid()

    Returns TRUE if the list pointer is valid.

  • int Count()

    Returns the number of nodes in the list.

  • MSXML2::IXMLDOMNode* Node(int index)

    Return the nth node in the list.

    Usage:

    for (int i = 0; i < nodeList.Count(); i++)
    {
         CXmlNodeWrapper node(nodeList.Node(i));
         // Do things
    }
  • void Start()

    Resets the iterator. See example in Next().

  • MSXML2::IXMLDOMNode* Next()

    Return the next node in the list when iterating or NULL if none.

    Usage:

    nodeList.Start();
    CXmlNodeWrapper node(nodeList.Next());
    while (node.IsValid())
    {
        // Do things
        node = nodeList.Next();
    }
  • MSXML2::IXMLDOMDocument* AsDocument()

    Converts the node list to a new document in the form: <NodeList>THENODES</NodeList>

    Usage:

    CXmlDocumentWrapper doc(theList.AsDocument());

Update

The sample is now available for download. Also a few more new functions are included:

  • int CXmlNodeWrapper::NumAttributes() - returns the number of attributes in the node.
  • CString CXmlNodeWrapper::NodeType() - returns the type of the node : "element", "text", etc.
  • CString CXmlNodeWrapper::GetAttribName(int index) - returns the name of the attribute at index.
  • CString CXmlNodeWrapper::GetAttribVal(int index) - returns the value of the attribute at index.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) RDV Systems
Israel Israel
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralRe: Use in a Windows Service Pin
Nandiator29-Dec-05 23:49
Nandiator29-Dec-05 23:49 
Generalsubtle memory issue Pin
.dan.g.7-Jun-05 16:56
professional.dan.g.7-Jun-05 16:56 
GeneralRe: subtle memory issue Pin
Alex Hazanov8-Jun-05 9:36
Alex Hazanov8-Jun-05 9:36 
GeneralRe: subtle memory issue Pin
.dan.g.8-Jun-05 14:32
professional.dan.g.8-Jun-05 14:32 
GeneralRe: subtle memory issue Pin
Alex Hazanov9-Jun-05 3:46
Alex Hazanov9-Jun-05 3:46 
GeneralRe: subtle memory issue Pin
Rouslan Grabar [Russ]15-Jun-05 2:01
Rouslan Grabar [Russ]15-Jun-05 2:01 
GeneralRe: subtle memory issue Pin
maury_7327-May-10 0:30
maury_7327-May-10 0:30 
GeneralTry it by your huge file please! Pin
andré_k16-Jun-05 13:04
andré_k16-Jun-05 13:04 
Dan, gospodin Hazanov's solution worked perfectly for me as it was,
Many, many thanks to him to share with us his xml in native(“unmanaged”) c++ experience

As suggested by your discussion, I modified the XmlNodeWrapper.cpp/.h files.
The project compiles and continues to work perfectly... (?!?) No leaks, nothing
Can you please say us if it changed something :

(To save Chris's server, I compressed a little the texts + Apologizes..)
===================== XmlNodeWrapper.h ===================
#pragma once
#import "MSXML3.dll" named_guids
using namespace MSXML2;
class CXmlNodeWrapper
{
public:
CString NodeType();
CString GetAttribVal(int index);
CString GetAttribName(int index);
int NumAttributes();
void ReplaceNode(MSXML2::IXMLDOMNodePtr pOldNode,MSXML2::IXMLDOMNodePtr pNewNode);
CString GetText();
void SetText(LPCTSTR text);
MSXML2::IXMLDOMNodePtr InsertAfter(MSXML2::IXMLDOMNodePtr refNode, MSXML2::IXMLDOMNodePtr pNode);
CString Name();
MSXML2::IXMLDOMNodeListPtr FindNodes(LPCTSTR searchStr);
MSXML2::IXMLDOMNodePtr Parent();
void RemoveNodes(LPCTSTR searchStr);
MSXML2::IXMLDOMNodePtr InsertAfter(MSXML2::IXMLDOMNodePtr refNode, LPCTSTR nodeName);
MSXML2::IXMLDOMNodePtr InsertBefore(MSXML2::IXMLDOMNodePtr refNode, LPCTSTR nodeName);
MSXML2::IXMLDOMNode* Interface();
MSXML2::IXMLDOMDocumentPtr ParentDocument();
CString GetXML();
MSXML2::IXMLDOMNodePtr RemoveNode(MSXML2::IXMLDOMNodePtr pNode);
MSXML2::IXMLDOMNodePtr InsertNode(int index,LPCTSTR nodeName);
MSXML2::IXMLDOMNodePtr InsertNode(int index,MSXML2::IXMLDOMNodePtr pNode);
long NumNodes();
MSXML2::IXMLDOMNode* Detach();
MSXML2::IXMLDOMNodePtr GetNode(LPCTSTR nodeName);
MSXML2::IXMLDOMNodePtr GetNode(int nodeIndex);
MSXML2::IXMLDOMNodePtr FindNode(LPCTSTR searchString);
MSXML2::IXMLDOMNodePtr GetPrevSibling();
MSXML2::IXMLDOMNodePtr GetNextSibling();
void SetValue(LPCTSTR valueName,LPCTSTR value);
void SetValue(LPCTSTR valueName,int value);
void SetValue(LPCTSTR valueName,short value);
void SetValue(LPCTSTR valueName,double value);
void SetValue(LPCTSTR valueName,float value);
void SetValue(LPCTSTR valueName,bool value);
BOOL IsValid();
CString GetValue(LPCTSTR valueName);
CXmlNodeWrapper();
CXmlNodeWrapper(MSXML2::IXMLDOMNodePtr pNode,BOOL bAutoRelease = TRUE);
void operator=(MSXML2::IXMLDOMNodePtr pNode);
virtual ~CXmlNodeWrapper();
private:
BOOL m_bAutoRelease;
MSXML2::IXMLDOMNodePtr m_xmlnode;
};

class CXmlDocumentWrapper
{
public:
CString GetUrl();
CString GetXML();
BOOL IsValid();
BOOL Load(LPCTSTR path);
BOOL LoadXML(LPCTSTR xml);
BOOL Save(LPCTSTR path = "");
MSXML2::IXMLDOMDocument* Detach();
MSXML2::IXMLDOMDocumentPtr Clone();
CXmlDocumentWrapper();
CXmlDocumentWrapper(MSXML2::IXMLDOMDocumentPtr pDoc);
MSXML2::IXMLDOMNodePtr AsNode();
virtual ~CXmlDocumentWrapper();
private:
MSXML2::IXMLDOMDocumentPtr m_xmldoc;
};

class CXmlNodeListWrapper
{
public:
MSXML2::IXMLDOMDocumentPtr AsDocument();
MSXML2::IXMLDOMNodePtr Node(int index);
void Start();
MSXML2::IXMLDOMNodePtr Next();
BOOL IsValid();
int Count();
CXmlNodeListWrapper();
CXmlNodeListWrapper(MSXML2::IXMLDOMNodeListPtr pList);
void operator=(MSXML2::IXMLDOMNodeListPtr pList);
virtual ~CXmlNodeListWrapper();
private:
MSXML2::IXMLDOMNodeListPtr m_xmlnodelist;
};
===================== XmlNodeWrapper.cpp =================
#include "stdafx.h"
#include "XmlNodeWrapper.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CXmlNodeWrapper::CXmlNodeWrapper() {}

CXmlNodeWrapper::CXmlNodeWrapper(MSXML2::IXMLDOMNodePtr pNode,BOOL bAutoRelease) {
m_xmlnode = pNode;
m_bAutoRelease = bAutoRelease;
}

void CXmlNodeWrapper::operator=(MSXML2::IXMLDOMNodePtr pNode) {
if (IsValid())
m_xmlnode.Release();
m_xmlnode = pNode;
}

CXmlNodeWrapper::~CXmlNodeWrapper() {
if (!m_bAutoRelease)
m_xmlnode.Detach();
}

CString CXmlNodeWrapper::GetValue(LPCTSTR valueName) {
if (!IsValid())
return "";
MSXML2::IXMLDOMNodePtr attribute = m_xmlnode->Getattributes()->getNamedItem(valueName);
if (attribute) {
return (LPCSTR)attribute->Gettext();
}
return "";
}

BOOL CXmlNodeWrapper::IsValid() {
if (m_xmlnode == NULL)
return FALSE;
if (m_xmlnode.GetInterfacePtr() == NULL)
return FALSE;
return TRUE;
}

MSXML2::IXMLDOMNodePtr CXmlNodeWrapper::GetPrevSibling() {
if (!IsValid())
return NULL;
return m_xmlnode->GetpreviousSibling(); //.Detach();
}

MSXML2::IXMLDOMNodePtr CXmlNodeWrapper::GetNextSibling() {
if (!IsValid())
return NULL;
return m_xmlnode->GetnextSibling(); //.Detach();
}

MSXML2::IXMLDOMNodePtr CXmlNodeWrapper::GetNode(LPCTSTR nodeName) {
if (!IsValid())
return NULL;
try{
return m_xmlnode->selectSingleNode(nodeName); //.Detach();
}
catch (_com_error e) {
CString err = e.ErrorMessage();
}
return NULL;
}

MSXML2::IXMLDOMNodePtr CXmlNodeWrapper::GetNode(int nodeIndex) {
if (!IsValid())
return NULL;
return m_xmlnode->GetchildNodes()->Getitem(nodeIndex); //.Detach();
}

MSXML2::IXMLDOMNodePtr CXmlNodeWrapper::FindNode(LPCTSTR searchString) {
if (!IsValid())
return NULL;
try{
return m_xmlnode->selectSingleNode(searchString); //.Detach();
}
catch (_com_error e) {
CString err = e.ErrorMessage();
}
return NULL;
}

MSXML2::IXMLDOMNode* CXmlNodeWrapper::Detach() {
if (IsValid()) {
return m_xmlnode.Detach();
}
else
return NULL;
}

long CXmlNodeWrapper::NumNodes() {
if (IsValid()) {
return m_xmlnode->GetchildNodes()->Getlength();
}
else
return 0;
}

void CXmlNodeWrapper::SetValue(LPCTSTR valueName,LPCTSTR value) {
MSXML2::IXMLDOMDocumentPtr xmlDocument = m_xmlnode->GetownerDocument();
if (xmlDocument) {
MSXML2::IXMLDOMNamedNodeMapPtr attributes = m_xmlnode->Getattributes();
if (attributes) {
MSXML2::IXMLDOMAttributePtr attribute = xmlDocument->createAttribute(valueName);
if (attribute) {
attribute->Puttext(value);
attributes->setNamedItem(attribute);
}
}
}
}

void CXmlNodeWrapper::SetValue(LPCTSTR valueName,int value) {
CString str;
str.Format("%ld",value);
SetValue(valueName,str);
}

void CXmlNodeWrapper::SetValue(LPCTSTR valueName,short value) {
CString str;
str.Format("%hd",value);
SetValue(valueName,str);
}

void CXmlNodeWrapper::SetValue(LPCTSTR valueName,double value) {
CString str;
str.Format("%f",value);
SetValue(valueName,str);
}

void CXmlNodeWrapper::SetValue(LPCTSTR valueName,float value) {
CString str;
str.Format("%f",value);
SetValue(valueName,str);
}

void CXmlNodeWrapper::SetValue(LPCTSTR valueName,bool value) {
CString str;
if (value)
str = "True";
else
str = "False";
SetValue(valueName,str);
}

MSXML2::IXMLDOMNodePtr CXmlNodeWrapper::InsertNode(int index,LPCTSTR nodeName) {
MSXML2::IXMLDOMDocumentPtr xmlDocument = m_xmlnode->GetownerDocument();
if (xmlDocument) {
MSXML2::IXMLDOMNodePtr newNode = xmlDocument->createNode(_variant_t((short)MSXML2::NODE_ELEMENT),nodeName,"");
MSXML2::IXMLDOMNodePtr refNode = GetNode(index);
if (refNode)
// newNode = m_xmlnode->insertBefore(newNode.Detach(),refNode);
newNode = m_xmlnode->insertBefore(newNode,(const _variant_t &)refNode);
else
newNode = m_xmlnode->appendChild(newNode); //.Detach());
return newNode; //.Detach();
}
return NULL;
}

MSXML2::IXMLDOMNodePtr CXmlNodeWrapper::InsertNode(int index,MSXML2::IXMLDOMNodePtr pNode) {
MSXML2::IXMLDOMNodePtr newNode = pNode->cloneNode(VARIANT_TRUE);
if (newNode) {
MSXML2::IXMLDOMNodePtr refNode = GetNode(index);
if (refNode)
newNode = m_xmlnode->insertBefore(newNode,(const _variant_t &)refNode);
else
newNode = m_xmlnode->appendChild(newNode); //.Detach());
return newNode; //.Detach();
}
else
return NULL;
}

CString CXmlNodeWrapper::GetXML() {
if (IsValid())
return (LPCSTR)m_xmlnode->Getxml();
else
return "";
}

MSXML2::IXMLDOMNodePtr CXmlNodeWrapper::RemoveNode(MSXML2::IXMLDOMNodePtr pNode) {
if (!IsValid())
return NULL;
return m_xmlnode->removeChild(pNode); //.Detach();
}

/* ************************************************ (vive CodeProject! ... etc..) */
CXmlDocumentWrapper::CXmlDocumentWrapper() {
m_xmldoc.CreateInstance(MSXML2::CLSID_DOMDocument);
}

CXmlDocumentWrapper::CXmlDocumentWrapper(MSXML2::IXMLDOMDocumentPtr pDoc) {
m_xmldoc = pDoc;
}

CXmlDocumentWrapper::~CXmlDocumentWrapper() {
}

BOOL CXmlDocumentWrapper::IsValid() {
if (m_xmldoc == NULL)
return FALSE;
if (m_xmldoc.GetInterfacePtr() == NULL)
return FALSE;
return TRUE;
}

MSXML2::IXMLDOMDocument* CXmlDocumentWrapper::Detach() {
if (!IsValid())
return NULL;
return m_xmldoc.Detach();
}

MSXML2::IXMLDOMDocumentPtr CXmlDocumentWrapper::Clone() {
if (!IsValid())
return NULL;
MSXML2::IXMLDOMDocumentPtr xmldoc;
xmldoc.CreateInstance(MSXML2::CLSID_DOMDocument);
_variant_t v(xmldoc.GetInterfacePtr());
m_xmldoc->save(v);
return xmldoc; //.Detach();
}

BOOL CXmlDocumentWrapper::Load(LPCTSTR path) {
if (!IsValid())
return FALSE;
_variant_t v(path);
m_xmldoc->put_async(VARIANT_FALSE);
VARIANT_BOOL success = m_xmldoc->load(v);
if (success == VARIANT_TRUE)
return TRUE;
else
return FALSE;
}

BOOL CXmlDocumentWrapper::LoadXML(LPCTSTR xml) {
if (!IsValid())
return FALSE;
VARIANT_BOOL success = m_xmldoc->loadXML(xml);
if (success == VARIANT_TRUE)
return TRUE;
else
return FALSE;
}

BOOL CXmlDocumentWrapper::Save(LPCTSTR path) {
try
{
if (!IsValid())
return FALSE;
CString szPath(path);
if (szPath == "") {
_bstr_t curPath = m_xmldoc->Geturl();
szPath = (LPSTR)curPath;
}
_variant_t v(szPath);
if (FAILED(m_xmldoc->save(v)))
return FALSE;
else
return TRUE;
}
catch(...) {
return FALSE;
}
}

MSXML2::IXMLDOMNodePtr CXmlDocumentWrapper::AsNode() {
if (!IsValid())
return NULL;
// plante ! : return m_xmldoc->GetdocumentElement(); //.Detach(); modif ... sans Detach
return m_xmldoc->GetdocumentElement(); //.Detach();
}

CString CXmlDocumentWrapper::GetXML() {
if (IsValid())
return (LPCSTR)m_xmldoc->Getxml();
else
return "";
}

CString CXmlDocumentWrapper::GetUrl() {
return (LPSTR)m_xmldoc->Geturl();
}

MSXML2::IXMLDOMDocumentPtr CXmlNodeWrapper::ParentDocument() {
return m_xmlnode->GetownerDocument(); //.Detach();
}

MSXML2::IXMLDOMNode* CXmlNodeWrapper::Interface() {
if (IsValid())
return m_xmlnode;
return NULL;
}

MSXML2::IXMLDOMNodePtr CXmlNodeWrapper::InsertBefore(MSXML2::IXMLDOMNodePtr refNode, LPCTSTR nodeName) {
MSXML2::IXMLDOMDocumentPtr xmlDocument = m_xmlnode->GetownerDocument();
if (xmlDocument) {
MSXML2::IXMLDOMNodePtr newNode = xmlDocument->createNode(_variant_t((short)MSXML2::NODE_ELEMENT),nodeName,"");
newNode = m_xmlnode->insertBefore(newNode,_variant_t(refNode.GetInterfacePtr()));
return newNode;
}
return NULL;
}

MSXML2::IXMLDOMNodePtr CXmlNodeWrapper::InsertAfter(MSXML2::IXMLDOMNodePtr refNode, LPCTSTR nodeName) {
MSXML2::IXMLDOMDocumentPtr xmlDocument = m_xmlnode->GetownerDocument();
if (xmlDocument) {
MSXML2::IXMLDOMNodePtr newNode = xmlDocument->createNode(_variant_t((short)MSXML2::NODE_ELEMENT),nodeName,"");
MSXML2::IXMLDOMNodePtr nextNode = refNode->GetnextSibling();
if (nextNode.GetInterfacePtr() != NULL)
newNode = m_xmlnode->insertBefore(newNode,_variant_t(nextNode.GetInterfacePtr()));
else
newNode = m_xmlnode->appendChild(newNode);
return newNode;
}
return NULL;
}

void CXmlNodeWrapper::RemoveNodes(LPCTSTR searchStr) {
if (!IsValid())
return;
MSXML2::IXMLDOMNodeListPtr nodeList = m_xmlnode->selectNodes(searchStr);
for (int i = 0; i < nodeList->Getlength(); i++) {
try
{
MSXML2::IXMLDOMNodePtr pNode = nodeList->Getitem(i); //.Detach();
pNode->GetparentNode()->removeChild(pNode);
}
catch (_com_error er) {
AfxMessageBox(er.ErrorMessage());
}
}
}

MSXML2::IXMLDOMNodePtr CXmlNodeWrapper::Parent() {
if (IsValid())
return m_xmlnode->GetparentNode(); //.Detach();
return NULL;
}

CXmlNodeListWrapper::CXmlNodeListWrapper() {
}

CXmlNodeListWrapper::CXmlNodeListWrapper(MSXML2::IXMLDOMNodeListPtr pList) {
m_xmlnodelist = pList;
}

void CXmlNodeListWrapper::operator=(MSXML2::IXMLDOMNodeListPtr pList) {
if (IsValid())
m_xmlnodelist.Release();
m_xmlnodelist = pList;
}

CXmlNodeListWrapper::~CXmlNodeListWrapper() {
}

int CXmlNodeListWrapper::Count() {
if (IsValid())
return m_xmlnodelist->Getlength();
else
return 0;
}

BOOL CXmlNodeListWrapper::IsValid() {
if (m_xmlnodelist == NULL)
return FALSE;
if (m_xmlnodelist.GetInterfacePtr() == NULL)
return FALSE;
return TRUE;
}

MSXML2::IXMLDOMNodePtr CXmlNodeListWrapper::Next() {
if (IsValid())
return m_xmlnodelist->nextNode(); //.Detach();
else
return NULL;
}

void CXmlNodeListWrapper::Start() {
if (IsValid())
m_xmlnodelist->reset();
}

MSXML2::IXMLDOMNodePtr CXmlNodeListWrapper::Node(int index) {
if (IsValid())
return m_xmlnodelist->Getitem(index); //.Detach();
else
return NULL;
}

MSXML2::IXMLDOMDocumentPtr CXmlNodeListWrapper::AsDocument() {
if (IsValid()) {
CXmlDocumentWrapper doc;
doc.LoadXML("<NodeList></NodeList>");
CXmlNodeWrapper root(doc.AsNode());
for (int i = 0; i < m_xmlnodelist->Getlength(); i++) {
root.InsertNode(root.NumNodes(),m_xmlnodelist->Getitem(i)->cloneNode(VARIANT_TRUE));
}
return doc.Detach();
}
else
return NULL;
}

MSXML2::IXMLDOMNodeListPtr CXmlNodeWrapper::FindNodes(LPCTSTR searchStr) {
if(IsValid()) {
try{
return m_xmlnode->selectNodes(searchStr); //.Detach();
}
catch (_com_error e) {
CString err = e.ErrorMessage();
return NULL;
}
}
else
return NULL;
}

CString CXmlNodeWrapper::Name() {
if (IsValid())
return (LPCSTR)m_xmlnode->GetbaseName();
return "";
}

MSXML2::IXMLDOMNodePtr CXmlNodeWrapper::InsertAfter(MSXML2::IXMLDOMNodePtr refNode, MSXML2::IXMLDOMNodePtr pNode) {
MSXML2::IXMLDOMNodePtr nextNode = refNode->GetnextSibling();
MSXML2::IXMLDOMNodePtr newNode;
if (nextNode.GetInterfacePtr() != NULL)
newNode = m_xmlnode->insertBefore(pNode,_variant_t(nextNode.GetInterfacePtr()));
else
newNode = m_xmlnode->appendChild(pNode);
return newNode;
}

void CXmlNodeWrapper::SetText(LPCTSTR text) {
if (IsValid())
m_xmlnode->Puttext(text);
}

CString CXmlNodeWrapper::GetText() {
if (IsValid())
return (LPCSTR)m_xmlnode->Gettext();
else
return "";
}

void CXmlNodeWrapper::ReplaceNode(MSXML2::IXMLDOMNodePtr pOldNode, MSXML2::IXMLDOMNodePtr pNewNode) {
if (IsValid()) {
m_xmlnode->replaceChild(pNewNode,pOldNode);
}
}

int CXmlNodeWrapper::NumAttributes() {
if (IsValid()) {
MSXML2::IXMLDOMNamedNodeMapPtr attribs = m_xmlnode->Getattributes();
if (attribs)
return attribs->Getlength();
}
return 0;
}

CString CXmlNodeWrapper::GetAttribName(int index) {
if (IsValid()) {
MSXML2::IXMLDOMNamedNodeMapPtr attribs = m_xmlnode->Getattributes();
if (attribs) {
MSXML2::IXMLDOMAttributePtr attrib = attribs->Getitem(index);
if (attrib)
return (LPCSTR)attrib->Getname();
}
}
return "";
}

CString CXmlNodeWrapper::GetAttribVal(int index) {
if (IsValid()) {
MSXML2::IXMLDOMNamedNodeMapPtr attribs = m_xmlnode->Getattributes();
if (attribs) {
MSXML2::IXMLDOMAttributePtr attrib = attribs->Getitem(index);
if (attrib)
return (LPCSTR)attrib->Gettext();
}
}
return "";
}

CString CXmlNodeWrapper::NodeType() {
if (IsValid())
return (LPCSTR)m_xmlnode->GetnodeTypeString();
return "";
}

GeneralRe: Try it by your huge file please! Pin
.dan.g.16-Jun-05 16:22
professional.dan.g.16-Jun-05 16:22 
GeneralReleasing Memory Pin
.dan.g.31-May-05 14:46
professional.dan.g.31-May-05 14:46 
GeneralRe: Releasing Memory Pin
Alex Hazanov31-May-05 21:02
Alex Hazanov31-May-05 21:02 
GeneralRe: Releasing Memory Pin
.dan.g.1-Jun-05 17:49
professional.dan.g.1-Jun-05 17:49 
GeneralLoad Failure @@... Pin
weilun27-May-05 4:19
weilun27-May-05 4:19 
GeneralRe: Load Failure @@... Pin
weilun27-May-05 21:52
weilun27-May-05 21:52 
GeneralRe: Load Failure @@... Pin
Snarfster13-Oct-05 11:42
Snarfster13-Oct-05 11:42 
GeneralResource Leak Pin
26-May-05 16:13
suss26-May-05 16:13 
GeneralRe: Resource Leak Pin
Alex Hazanov27-May-05 1:46
Alex Hazanov27-May-05 1:46 
GeneralRe: Resource Leak Pin
Member 28654627-May-05 1:52
Member 28654627-May-05 1:52 
GeneralRe: Resource Leak Pin
Alex Hazanov28-May-05 10:59
Alex Hazanov28-May-05 10:59 
GeneralAnother look at XML file Pin
Reveur129-Apr-05 10:21
Reveur129-Apr-05 10:21 
GeneralRe: Another look at XML file Pin
Alex Hazanov1-May-05 1:00
Alex Hazanov1-May-05 1:00 
GeneralRe: Another look at XML file Pin
Reveur15-May-05 13:32
Reveur15-May-05 13:32 
GeneralXML Parser Pin
Reveur129-Apr-05 10:14
Reveur129-Apr-05 10:14 
Generalcreating document from scratch Pin
.dan.g.27-Apr-05 0:38
professional.dan.g.27-Apr-05 0:38 
GeneralRe: creating document from scratch Pin
.dan.g.27-Apr-05 13:53
professional.dan.g.27-Apr-05 13:53 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.