加载文档大体上分为三步:
1
.使用
CreateInstance
方法创建分析器实例;
2
.设置
async
属性为
False
,禁止异步加载,这样当文档加载完毕,控制权才会返回给调用
进程,如果想获取文档加载状态,可以读取
readyState
属性值;
3
.使用
load
方法加载指定文档。
XML DOM
还提供了一种
loadXML
的方法可以把
XML
字符串加
载到
DOM
树中,使用时只要把
XML
字符串直接作为该方法的参数即可。
常用的类型:
IXMLDOMDocumentPtr docPtr;
IXMLDOMNodePtr DOMNodePtr;
IXMLDOMNodeListPtr NodeListPtr;
加载一个文档或者一段
XML
的方法:
CoInitialize(NULL);
docPtr.CreateInstance("msxml2.domdocument");
// load a document
_variant_t varXml("book1.xml");
需要加载的
XML
文档
_variant_t varOut((bool)TRUE);
varOut = docPtr->loadXML(_T("<AddrBook></AddrBook>"));
加载一段
XML
字符串。
或者加载一个
XML
文档——
varOut = docPtr->load(varXml);
3、
DOM
树的访问
在文档加载完毕之后就可以使用上面所示的三种类型接口访问
XML
文档。可以做你能想到的所
有的事情。加入一个节点,删除,插入,替换,取得节点名,取得节点内容等等。
下面是一个创建一个
XML
文档和分析它的简单程序。
_variant_t varTyp((short)NODE_ELEMENT);//Node
属性为元素!
_bstr_t varName(_T("Addr"));//Node
名为“
Addr
”
IXMLDOMNodePtr nodePtr= docPtr->createNode(varTyp, varName, "");//
创建一个
Node
//
创建一个
XML
片断并在它的上面加几个
Node
。
IXMLDOMDocumentFragmentPtr fragPtr = docPtr->createDocumentFragment();
HRESULT hr = fragPtr->appendChild(nodePtr);
//
添加一个以
Name
为名的
Node
。
varName = _T("Name");
IXMLDOMNodePtr nodePtr1= docPtr->createNode(varTyp, varName, "");
nodePtr1->text = _T("Wenqy");
hr = nodePtr->appendChild(nodePtr1);
//
添加一个以
Street
为名的
Node
。
varName = "Street";
IXMLDOMNodePtr nodePtr2= docPtr->createNode(varTyp, varName, "");
nodePtr2->text = _T("Sanhao Street");
hr = nodePtr->appendChild(nodePtr2);
//
创建一个
PhoneNumbers Node
。
varName = _T("PhoneNumbers");
IXMLDOMNodePtr nodePtr3= docPtr->createNode(varTyp, varName, "");
//
在
PhoneNumbers Node
上添加一个子
Node
——
PhoneNumber
。
varName = _T("PhoneNumber");
IXMLDOMNodePtr nodePtr4= docPtr->createNode(varTyp, varName, "");
nodePtr4->text = _T("024-23783000");
hr = nodePtr3->appendChild(nodePtr4);
//
将
PhoneNumbers Node
添加在
XML
片断上。
hr = nodePtr->appendChild(nodePtr3);
//
添加一个
Age Node
。
varName = _T("Age");
IXMLDOMNodePtr nodePtr5= docPtr->createNode(varTyp, varName, "");
nodePtr5->text = _T("26");
hr = nodePtr->appendChild(nodePtr5);
//
将片断添加在原来的文档上。
hr = docPtr->documentElement->appendChild(fragPtr);
//
保存我们创建的文档在一个真正的文档内。
hr = docPtr->save(varXml);
//XML
的遍历主要使用
IXMLDOMNodeListPtr
接口
//
它的作用就是将一类标签相同的
Node
提取出来,然后利用它自身提供的接口遍历之。
NodeListPtr = docPtr->getElementsByTagName(_T("Addr"));
//
取得
NodeList
中
Node
的个数。
long iLength;
NodeListPtr->get_length(&iLength);
//
遍历之——
for(int i = 0;i < iLength;i++)
{
//
取得一个
Node
。
nodePtr = NodeListPtr->Getitem(i);
//
取得
Node
名
BSTR bstr;
nodePtr->get_nodeName(&bstr);
CString csTemp = bstr;
//
取得此
Node
的孩子
NodeList
IXMLDOMNodeListPtr NodeListChild = nodePtr->GetchildNodes();
long iLeng;
NodeListChild->get_length(&iLeng);
//
遍历其孩子
NodeList
for(int j = 0;j < iLeng;j++)
{
BSTR bstrTemp;
nodePtr1 = NodeListChild->Getitem(j);
nodePtr1->get_nodeName(&bstrTemp);
CString cs1 = bstrTemp;
if(cs1 == "Age")
{
CString cs2;
nodePtr1->get_text(&bstrTemp);
cs2 = bstrTemp;
}
if((cs1 == "Name")||(cs1 == "Street"))
{
CString cs2;
nodePtr1->get_text(&bstrTemp);
cs2 = bstrTemp;
}
if(cs1 == "PhoneNumbers")
{
CString cs2;
IXMLDOMNodeListPtr NodeListGrandchild=nodePtr1-
>GetchildNodes();
long len;
NodeListGrandchild->get_length(&len);
for(int k = 0;k<len;k++)
{
BSTR bstrTemp;
nodePtr2 = NodeListChild->Getitem(j);
CString cs3 = bstrTemp= nodePtr2->GetnodeName();
bstrTemp = nodePtr2->Gettext();
CString cs4 = bstrTemp;
}
}
}
}
Document
对象中的
getElementsByTagName
方法就是根据参数中的标签名称在全文范围内查找
元素的,返回值是一个
NodeList
对象:
getElementsByTagName
方法,除了搜索范围缩小为该元素的所有后继节点之外,其他的情况
都是一样的。
所有类型的节点都带有
selectNodes
方法,该方法的唯一参数是
XSL
的模式规则,返回值是匹
配该规则的结果集合。调用这个方法可以利用
XSL
的模式匹配策略查找节点。
另外,节点中的
selectSingleNodes
方法的用法与
selectNodes
是一样的,只是返回结果为查
找到的满足条件的第一个节点而已。
对于元素节点,获取元素标签名称的方法有两种:
anyElement.nodeName
和
anyElement.tagName
。前者是
Node
对象的属性,后者是
Element
对象的属性。
如果想获取元素中的文本内容,如
: <price>9.95 </price>
时,访问
Element
对象中的
nodeValue
属性是错误的,这时返回结果是
null
,而不是预期的
9.95
。含有文本内容的元素
都包含一个
Text
类型的子节点,所以只有通过
Text
对象中的
nodeValue
属性才能真正访问到
文本内容。(这里是
VB
的一些用法)
注意:
1
.
BSTR
与
char*
之间的转换;
BSTR
就是
OLECHAR
型,是一个双字节的字符串。
从一个
char*
向
BSTR
转换:
char cName[] =
“
wenqy
”
;
BSTR bstrName = SysAllocString(OLESTR(cName));
它的释放函数是
SysFreeString(bstrName);
从一个
BSTR
向
char*
转换:
BSTR bstrName = SysAllocString(OLESTR(
“
wenqy
”
));
char *cName = new char[6];
_wcstombsz (cName,bstrName,
关于
SOAP
的操作
在
StdAfx.h
中引入:
#include "objbase.h"
#import "msxml3.dll"
using namespace MSXML2;
#import "C:\Program Files\Common Files\MSSoap\Binaries\mssoap1.dll"
exclude("IStream", "ISequentialStream", "_LARGE_INTEGER", "_ULARGE_INTEGER",
"tagSTATSTG", "_FILETIME")
using namespace MSSOAPLib;
这是使用
MSSOAP
的必要准备。
MSXML3.dll
中包含对
XML
的解析操作内容。
Mssoap1.dll
是
SOAPClient
等使用
SOAP
的操作。
在服务端我们使用
COM
组件提供了服务。这些
COM
组件与一般的组件没有任何区别。除了需要
对复合类型进行一些特殊的操作外(指需要使用
IXMLDOMNodeList
传递),其他没有了。
SOAPClient
使用步骤:
1
创建一个实例——
>2
使用
WSDL
初始化
SOAPClient
——
>3
根据方法名取得
DISPID
——
>4
根
据
DISPID
调用方法。
1
.创建实例
hr = m_pSoapClient.CreateInstance(__uuidof(SoapClient));
2
.使用
WSDL
初始化
SOAPClient
hr = m_pSoapClient->mssoapinit((LPCTSTR)m_wsdl, _T(""), _T(""), _T(""));
3
.根据方法名取得
DISPID
hr = m_pSoapClient->GetIDsOfNames(IID_NULL, &pMethodName, 1,
LOCALE_SYSTEM_DEFAULT, &dispid);
参数说明:
OLECHAR *pMethodName;
4
.根据
DISPID
调用方法
hr = m_pSoapClient->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT,
DISPATCH_METHOD, &dispparams,
&result,NULL,NULL);
VARIANT
中
SafeArray
的用法
向一个
SafeArray
中保存数据,然后填入一个
VARIANT
的类型:
SAFEARRAY* psa;
SAFEARRAYBOUND rgsabound[1];
rgsabound[0].lLbound = 0;
rgsabound[0].cElements = ulTotal;//
你要保存的
Buffer
的大小
psa = SafeArrayCreate(VT_UI1, 1, rgsabound);
for (long i = 0; i < (long)ulTotal; i++)
SafeArrayPutElement (psa, &i, pBufEx++);// pBufEx
是你要保存的
Buffer
//
把安全数组包裹在
VARIANT
变量
varBLOB
中
//1.
定义包裹变量
varBLOB
VARIANT varBLOB;
VariantInit(&varBLOB);
V_VT(&varBLOB) = VT_ARRAY|VT_UI1;//SafeArray
在
VARIANT
中的类型
V_ARRAY(&varBLOB) = psa;
访问
SafeArray
,读出数据:
if(varBLOB.vt == (VT_ARRAY | VT_UI1))
{
//
取出装载位图数据的安全数组上下界
long lLBound, lUBound;
SafeArrayGetLBound(varBLOB.parray, 1, &lLBound);
SafeArrayGetUBound(varBLOB.parray, 1, &lUBound);
//
位图数据字节总数数
long lDataSize = lUBound - lLBound + 1;
//
分配位图缓存
m_pBMPBuffer
if(m_pBMPBuffer = new BYTE[lDataSize+1]) //
重新分配必要的存储空间
{
char *pBuf = NULL;
SafeArrayAccessData(varBLOB.parray,(void **)&pBuf);
memcpy(m_pBMPBuffer,pBuf,lDataSize); //
复制数据到缓冲区
m_pBMPBuffer
m_iLength = lDataSize;
SafeArrayUnaccessData (varBLOB.parray);
}
}
VariantClear(&varBLOB);
望采纳,谢谢!!!
温馨提示:内容为网友见解,仅供参考