==========
XML文件
==========
<?xml version="1.0"?>
<catalog>
<book id="bk101">
<author>Gambardella, Matthew</author>
<title>XML Developer's Guide</title>
<genre>Computer</genre>
<price>44.95</price>
<publish_date>2000-10-01</publish_date>
<description>
An in-depth look at creating applications with XML.
</description>
</book>
<book id="bk102">
<author>Ralls, Kim</author>
<title>Midnight Rain</title>
<genre>Fantasy</genre>
<price>5.95</price>
<publish_date>2000-12-16</publish_date>
<description>
A former architect battles corporate zombies, an evil sorceress, and her own childhood to become queen of the world.
</description>
</book>
<book id="bk103">
<author>Corets, Eva</author>
<title>Maeve Ascendant</title>
<genre>Fantasy</genre>
<price>5.95</price>
<publish_date>2000-11-17</publish_date>
<description>
After the collapse of a nanotechnology society in England, the young survivors lay the foundation for a new society.
</description>
</book>
<book id="bk104">
<author>Corets, Eva</author>
<title>Oberon's Legacy</title>
<genre>Fantasy</genre>
<price>5.95</price>
<publish_date>2001-03-10</publish_date>
<description>
In post-apocalypse England, the mysterious agent known only as Oberon helps to create a new life for the inhabitants of London. Sequel to Maeve Ascendant.
</description>
</book>
<book id="bk105">
<author>Corets, Eva</author>
<title>The Sundered Grail</title>
<genre>Fantasy</genre>
<price>5.95</price>
<publish_date>2001-09-10</publish_date>
<description>
The two daughters of Maeve, half-sisters, battle one another for control of England. Sequel to Oberon's Legacy.
</description>
</book>
<book id="bk106">
<author>Randall, Cynthia</author>
<title>Lover Birds</title>
<genre>Romance</genre>
<price>4.95</price>
<publish_date>2000-09-02</publish_date>
<description>
When Carla meets Paul at an ornithology conference, tempers fly as feathers get ruffled.
</description>
</book>
<book id="bk107">
<author>Thurman, Paula</author>
<title>Splish Splash</title>
<genre>Romance</genre>
<price>4.95</price>
<publish_date>2000-11-02</publish_date>
<description>
A deep sea diver finds true love twenty thousand leagues beneath the sea.
</description>
</book>
<book id="bk108">
<author>Knorr, Stefan</author>
<title>Creepy Crawlies</title>
<genre>Horror</genre>
<price>4.95</price>
<publish_date>2000-12-06</publish_date>
<description>
An anthology of horror stories about roaches, centipedes, scorpions and other insects.
</description>
</book>
<book id="bk109">
<author>Kress, Peter</author>
<title>Paradox Lost</title>
<genre>Science Fiction</genre>
<price>6.95</price>
<publish_date>2000-11-02</publish_date>
<description>
After an inadvertant trip through a Heisenberg Uncertainty Device, James Salway discovers the problems of being quantum.
</description>
</book>
<book id="bk110">
<author>O'Brien, Tim</author>
<title>Microsoft .NET: The Programming Bible</title>
<genre>Computer</genre>
<price>36.95</price>
<publish_date>2000-12-09</publish_date>
<description>
Microsoft's .NET initiative is explored in detail in this deep programmer's reference.
</description>
</book>
<book id="bk111">
<author>O'Brien, Tim</author>
<title>MSXML3: A Comprehensive Guide</title>
<genre>Computer</genre>
<price>36.95</price>
<publish_date>2000-12-01</publish_date>
<description>
The Microsoft MSXML3 parser is covered in detail, with attention to XML DOM interfaces, XSLT processing, SAX and more.
</description>
</book>
<book id="bk112">
<author>Galos, Mike</author>
<title>Visual Studio 7: A Comprehensive Guide</title>
<genre>Computer</genre>
<price>49.95</price>
<publish_date>2001-04-16</publish_date>
<description>
Microsoft Visual Studio 7 is explored in depth, looking at how Visual Basic, Visual C++, C#, and ASP+ are integrated into a comprehensive development environment.
</description>
</book>
</catalog>
=============
HelperFunctions.h
=============
// Macro that calls a COM method returning HRESULT value:
#define HRCALL(a, errmsg) \
do { \
hr = (a); \
if (FAILED(hr)) { \
dprintf( "%s:%d\n HRCALL Failed: %s\n 0x%.8x = %s\n", \
__FILE__, __LINE__, errmsg, hr, #a ); \
goto clean; \
} \
} while (0)
// Helper function that put output in stdout and debug window in Visual Studio:
void dprintf( char *format, ...)
{
static char buf[65536];
va_list args;
va_start( args, format );
vsprintf_s( buf, format, args );
va_end( args);
OutputDebugStringA( buf);
printf("%s", buf);
}
// Helper function to create a DOM instance:
IXMLDOMDocument *DomFromCOM()
{
HRESULT hr;
IXMLDOMDocument *pxmldoc = NULL;
HRCALL (CoCreateInstance(__uuidof(DOMDocument60), NULL, CLSCTX_INPROC_SERVER, __uuidof(IXMLDOMDocument), (void**)&pxmldoc), "Create a new DOMDocument");
HRCALL (pxmldoc->put_async(VARIANT_FALSE), "should never fail");
HRCALL (pxmldoc->put_validateOnParse(VARIANT_FALSE), "should never fail");
HRCALL (pxmldoc->put_resolveExternals(VARIANT_FALSE), "should never fail");
return pxmldoc;
clean:
if (pxmldoc) pxmldoc->Release();
return NULL;
}
// Helper function to display xml parse error:
void ReportParseError(IXMLDOMDocument *pDom, char *desc)
{
IXMLDOMParseError *pXMLErr=NULL;
BSTR bstrReason = NULL;
HRESULT hr;
HRCALL(pDom->get_parseError(&pXMLErr), "dom->get_parseError: ");
HRCALL(pXMLErr->get_reason(&bstrReason), "parseError->get_reason: ");
dprintf("%s %S\n",desc, bstrReason);
clean:
if (pXMLErr) pXMLErr->Release();
if (bstrReason) SysFreeString(bstrReason);
}
// Helper function to append a whitespace text node to a specified element:
void AddWhiteSpaceToNode(IXMLDOMDocument* pDom, BSTR bstrWs, IXMLDOMNode *pNode)
{
HRESULT hr;
IXMLDOMText *pws=NULL;
IXMLDOMNode *pBuf=NULL;
HRCALL(pDom->createTextNode(bstrWs,&pws), " ");
HRCALL(pNode->appendChild(pws,&pBuf)," ");
clean:
if (pws) pws->Release();
pws=NULL;
if (pBuf) pBuf->Release();
pBuf=NULL;
}
VARIANT VariantString(BSTR str)
{
VARIANT var;
VariantInit(&var);
V_BSTR(&var) = SysAllocString(str);
V_VT(&var) = VT_BSTR;
return var;
}
//追加
void AppendChildToParent(IXMLDOMNode *pChild, IXMLDOMNode *pParent)
{
HRESULT hr;
IXMLDOMNode *pNode=NULL;
HRCALL(pParent->appendChild(pChild, &pNode), "");
clean:
if (pNode) pNode->Release();
pNode=NULL;
}
=============
主程序
=============
#include <stdio.h>
#include <msxml6.h>
#include "HelperFunctions.h"
#include <comdef.h>
#define PrintXML \
pBook->get_xml(&bstr123);\
dprintf("\n%S\n", bstr123);
int main()
{
IXMLDOMDocument *pXMLDom = NULL;
IXMLDOMParseError *pXMLErr = NULL;
BSTR bstr = NULL;
VARIANT_BOOL status;
VARIANT var;
HRESULT hr;
CoInitialize(NULL);
pXMLDom = DomFromCOM();
if (!pXMLDom) goto clean;
BSTR bstr123 = NULL; //测试用
//读取xml文件
VariantInit(&var);
V_BSTR(&var) = SysAllocString(L"Books.xml");
V_VT(&var) = VT_BSTR;
HRCALL(pXMLDom->load(var, &status), "");
if (&var)
VariantClear(&var);
if (status!=VARIANT_TRUE)
{
HRCALL(pXMLDom->get_parseError(&pXMLErr),"");
HRCALL(pXMLErr->get_reason(&bstr),"");
dprintf("Failed to load DOM from Books.xml. %S\n", bstr);
goto clean;
}
//打印xml文件内容
HRCALL(pXMLDom->get_xml(&bstr), "");
dprintf("XML DOM loaded from Books.xml:\n%S\n\n", bstr);
//获得所有书的属性
long NumofBooks = 0;
long NumofProperties = 0;
int i = 0;
int j = 0;
IXMLDOMNodeList *pBookList = NULL;
IXMLDOMNodeList *pBook_childlist = NULL;
IXMLDOMNode *pBook = NULL;
IXMLDOMNode *pBook_child = NULL;
BSTR bookbstr = NULL;
HRCALL(pXMLDom->getElementsByTagName(L"book", &pBookList), "");
HRCALL(pBookList->get_length(&NumofBooks), "");
printf("There are %d books in all.\n", NumofBooks);
//获取属性的数量
HRCALL(pBookList->get_item(0, &pBook), "");
HRCALL(pBook->get_childNodes(&pBook_childlist), "");
HRCALL(pBook_childlist->get_length(&NumofProperties), "");
//打印
for (i=0; i<NumofBooks; i++)
{
HRCALL(pBookList->get_item(i, &pBook), "");
printf("\nThis is the book No.%d:\t\n", i+1);
for (j=0; j<NumofProperties; j++)
{
HRCALL(pBook->get_childNodes(&pBook_childlist), "");
HRCALL(pBook_childlist->get_item(j, &pBook_child), "");
HRCALL(pBook_child->get_nodeName(&bstr), "");
dprintf("%S:\t", bstr);
HRCALL(pBook_child->get_text(&bookbstr), "");
dprintf("%S\n", bookbstr);
}
}
if (pBookList)
pBookList->Release();
if (pBook)
pBook->Release();
if (pBook_childlist)
pBook_childlist->Release();
if (pBook_child)
pBook_child->Release();
if (bstr)
SysFreeString(bstr);
if (bookbstr)
SysFreeString(bookbstr);
//打印Fantasy类书籍
printf("\n\nFantasy books are listed below.\n");
IXMLDOMNode *pBooktag = NULL;
bookbstr=L"Fantasy";
int count = 0;
HRCALL(pXMLDom->getElementsByTagName(L"book", &pBookList), "");
HRCALL(pBookList->get_length(&NumofBooks), "");
HRCALL(pBookList->get_item(0, &pBook), "");
HRCALL(pBook->get_childNodes(&pBook_childlist), "");
HRCALL(pBook_childlist->get_length(&NumofProperties), "");
for (i=0; i<NumofBooks; i++)
{
HRCALL(pBookList->get_item(i, &pBook), "");
HRCALL(pBook->get_childNodes(&pBook_childlist), "");
HRCALL(pBook_childlist->get_item(2, &pBooktag), "");
HRCALL(pBooktag->get_text(&bstr), "");
if (_bstr_t(bstr)==_bstr_t(bookbstr))
{
printf("\nThis is the fantasy book No.%d:\n", count+1);
count++;
for(j=0; j<NumofProperties; j++)
{
HRCALL(pBook_childlist->get_item(j, &pBook_child), "");
HRCALL(pBook_child->get_nodeName(&bstr), "");
dprintf("%S:\t", bstr);
HRCALL(pBook_child->get_text(&bstr), "");
dprintf("%S\n", bstr);
}
}
}
if (pBookList)
pBookList->Release();
if (pBook)
pBook->Release();
if (pBook_childlist)
pBook_childlist->Release();
if (pBook_child)
pBook_child->Release();
if (pBooktag)
pBooktag->Release();
if (bstr)
SysFreeString(bstr);
bookbstr = NULL;
//追加新书
/*
</book>
<book id="bk113">
<author>Sydney, Losstarot</author>
<title>New Book</title>
<genre>Computer</genre>
<price>10,000.00</price>
<publish_date>2400-02-29</publish_date>
<description>
A new book for test.
</description>
</book>
*/
printf("\n\nA new book will be appended.\n");
IXMLDOMElement *eBook = NULL;
IXMLDOMAttribute *pBookID = NULL;
HRCALL(pXMLDom->selectSingleNode(L"catalog", &pBook), "");
HRCALL(pXMLDom->createElement(L"book", &eBook), "");
HRCALL(pXMLDom->createAttribute(L"id", &pBookID), "");
var=VariantString(L"bk113");
HRCALL(pBookID->put_value(var), "");
HRCALL(eBook->setAttributeNode(pBookID, NULL), "");
AppendChildToParent(eBook, pBook);
if (pBookID)
pBookID->Release();
bstr=L"\n\t\t";
pBook->get_childNodes(&pBookList);
pBookList->get_length(&NumofBooks);
pBookList->get_item((NumofBooks-1), &pBook);
if (pBookList)
pBookList->Release();
AddWhiteSpaceToNode(pXMLDom, bstr, pBook);
HRCALL(pXMLDom->createElement(L"author", &eBook), "");
HRCALL(eBook->put_text(L"Jiawei, Lin"), "");
AppendChildToParent(eBook, pBook);
AddWhiteSpaceToNode(pXMLDom, bstr, pBook);
HRCALL(pXMLDom->createElement(L"title", &eBook), "");
HRCALL(eBook->put_text(L"New Book"), "");
AppendChildToParent(eBook, pBook);
AddWhiteSpaceToNode(pXMLDom, bstr, pBook);
HRCALL(pXMLDom->createElement(L"genre", &eBook), "");
HRCALL(eBook->put_text(L"Computer"), "");
AppendChildToParent(eBook, pBook);
AddWhiteSpaceToNode(pXMLDom, bstr, pBook);
HRCALL(pXMLDom->createElement(L"price", &eBook), "");
HRCALL(eBook->put_text(L"10,000.00"), "");
AppendChildToParent(eBook, pBook);
AddWhiteSpaceToNode(pXMLDom, bstr, pBook);
HRCALL(pXMLDom->createElement(L"publish_date", &eBook), "");
HRCALL(eBook->put_text(L"2400-02-29"), "");
AppendChildToParent(eBook, pBook);
AddWhiteSpaceToNode(pXMLDom, bstr, pBook);
HRCALL(pXMLDom->createElement(L"description", &eBook), "");
HRCALL(eBook->put_text(L"\n\t\t\tA new book for test.\n\t\t"), "");
AppendChildToParent(eBook, pBook);
if (eBook)
eBook->Release();
bstr = NULL;
AddWhiteSpaceToNode(pXMLDom, L"\n", pBook);
PrintXML;
var=VariantString(L"Books2.xml");
HRCALL(pXMLDom->save(var), "");
if (pBook)
pBook->Release();
if (&var)
VariantClear(&var);
//删除最后一本书
/*
</book>
<book id="bk113">
<author>Sydney, Losstarot</author>
<title>New Book</title>
<genre>Computer</genre>
<price>10,000.00</price>
<publish_date>2400-02-29</publish_date>
<description>
A new book for test.
</description>
</book>
*/
printf("\nThe last book will be deleted.\n");
IXMLDOMNode *pDelete = NULL;
HRCALL(pXMLDom->getElementsByTagName(L"catalog", &pBookList), "");
HRCALL(pBookList->get_item(0, &pBook), "");
HRCALL(pBook->get_lastChild(&pDelete), "");
HRCALL(pBook->removeChild(pDelete, NULL), "");
var=VariantString(L"Books3.xml");
HRCALL(pXMLDom->save(var), "");
if (pBookList)
pBookList->Release();
if (pDelete)
pDelete->Release();
if (pBook)
pBook->Release();
if (&var)
VariantClear(&var);
//在第一第二本书之间插入新书
/*
</book>
<book id="bk113">
<author>Sydney, Losstarot</author>
<title>New Book</title>
<genre>Computer</genre>
<price>10,000.00</price>
<publish_date>2400-02-29</publish_date>
<description>
A new book for test.
</description>
</book>
*/
IXMLDOMNode *pTemp = NULL;
HRCALL(pXMLDom->getElementsByTagName(L"book", &pBookList), "");
HRCALL(pBookList->get_item(1, &pTemp), "");
HRCALL(pXMLDom->selectSingleNode(L"catalog", &pBook), "");
HRCALL(pXMLDom->createElement(L"book", &eBook), "");
HRCALL(pXMLDom->createAttribute(L"id", &pBookID), "");
var=VariantString(L"bk113");
HRCALL(pBookID->put_value(var), "");
HRCALL(eBook->setAttributeNode(pBookID, NULL), "");
HRCALL(pBook->insertBefore(eBook, _variant_t(pTemp), NULL), "");
if (pBookID)
pBookID->Release();
if (pTemp)
pTemp->Release();
bstr=L"\n\t\t";
HRCALL(pXMLDom->getElementsByTagName(L"book", &pBookList), "");
HRCALL(pBookList->get_item(1, &pBook), "");
if (pBookList)
pBookList->Release();
AddWhiteSpaceToNode(pXMLDom, bstr, pBook);
HRCALL(pXMLDom->createElement(L"author", &eBook), "");
HRCALL(eBook->put_text(L"Jiawei, Lin"), "");
AppendChildToParent(eBook, pBook);
AddWhiteSpaceToNode(pXMLDom, bstr, pBook);
HRCALL(pXMLDom->createElement(L"title", &eBook), "");
HRCALL(eBook->put_text(L"New Book"), "");
AppendChildToParent(eBook, pBook);
AddWhiteSpaceToNode(pXMLDom, bstr, pBook);
HRCALL(pXMLDom->createElement(L"genre", &eBook), "");
HRCALL(eBook->put_text(L"Computer"), "");
AppendChildToParent(eBook, pBook);
AddWhiteSpaceToNode(pXMLDom, bstr, pBook);
HRCALL(pXMLDom->createElement(L"price", &eBook), "");
HRCALL(eBook->put_text(L"10,000.00"), "");
AppendChildToParent(eBook, pBook);
AddWhiteSpaceToNode(pXMLDom, bstr, pBook);
HRCALL(pXMLDom->createElement(L"publish_date", &eBook), "");
HRCALL(eBook->put_text(L"2400-02-29"), "");
AppendChildToParent(eBook, pBook);
AddWhiteSpaceToNode(pXMLDom, bstr, pBook);
HRCALL(pXMLDom->createElement(L"description", &eBook), "");
HRCALL(eBook->put_text(L"\n\t\t\tA new book for test.\n\t\t"), "");
AppendChildToParent(eBook, pBook);
AddWhiteSpaceToNode(pXMLDom, L"\n", pBook);
PrintXML;
if (pBook)
pBook->Release();
if (eBook)
eBook->Release();
bstr = NULL;
var=VariantString(L"Books4.xml");
HRCALL(pXMLDom->save(var), "");
if (&var)
VariantClear(&var);
//删除新书"bk113"
/*
</book>
<book id="bk113">
<author>Sydney, Losstarot</author>
<title>New Book</title>
<genre>Computer</genre>
<price>10,000.00</price>
<publish_date>2400-02-29</publish_date>
<description>
A new book for test.
</description>
</book>
*/
IXMLDOMNamedNodeMap *pNodeMap = NULL;
HRCALL(pXMLDom->getElementsByTagName(L"book", &pBookList),"");
HRCALL(pBookList->get_length(&NumofBooks), "");
for (i=0; i<NumofBooks; i++)
{
HRCALL(pBookList->get_item(i, &pBook_child), "");
HRCALL(pBook_child->get_attributes(&pNodeMap), "");
HRCALL(pNodeMap->getNamedItem(L"id", &pTemp), "");
HRCALL(pTemp->get_nodeValue(&var), "");
if (_variant_t(var)==VariantString(L"bk113"))
{
HRCALL(pBook_child->get_parentNode(&pBook), "");
HRCALL(pBook->removeChild(pBook_child, NULL), "");
break;
}
}
if (pBookList)
pBookList->Release();
if (pBook)
pBook->Release();
if (pNodeMap)
pNodeMap->Release();
if (pTemp)
pTemp->Release();
if (pBook_child)
pBook_child->Release();
var=VariantString(L"Books5.xml");
HRCALL(pXMLDom->save(var), "");
if (&var)
VariantClear(&var);
clean:
if (pXMLDom)
pXMLDom->Release();
if (pXMLErr)
pXMLErr->Release();
if (bstr)
SysFreeString(bstr);
if (&var)
VariantClear(&var);
CoUninitialize();
return 0;
}
