C语言也可以用IXMLDOMDocument来解析XML:
【C语言调用Win32 COM组件】C语言通过COM创建快捷方式、设置Win7任务栏图标进度条、使用MSXML6.0的IXMLDOMDocument读取XML文件的方法_c语言调用com-CSDN博客文章浏览阅读805次。Win32下的COM组件其实也可以在不支持类的C语言里面使用。以下为示例代码。/* 这个程序只能在C编译器下编译成功, 请确保源文件的扩展名为c */#define COBJMACROS#include #include #include #include #pragma comment(lib, "msxml6.lib")static HANDLE _c语言调用comhttps://blog.csdn.net/ZLK1214/article/details/106675423
C语言通过MSXML6.0读写XML文件(同时支持char[]和wchar_t[]字符数组)-CSDN博客文章浏览阅读240次,点赞3次,收藏2次。开发环境:Visual Studio 2010运行环境:Windows XP SP3。https://blog.csdn.net/ZLK1214/article/details/135662458【C++程序】
#include
#include
#pragma comment(lib, "msxml6.lib")
/*
参考资料:
(1) VARIANT结构体: https://msdn.microsoft.com/en-us/library/windows/desktop/dd373687(v=vs.85).aspx
VARIANT用于表示一个弱类型的变量
(2) BSTR字符串: https://msdn.microsoft.com/en-us/library/windows/desktop/ms221069(v=vs.85).aspx
BSTR字符串是用于COM组件对象模型的字符串格式, 字符串以表示字符串长度的4字节整数开始, 然后跟上UTF-16编码的wchar_t字符串(包括\0结束标志)。BSTR类型的变量是一个指针, 指向字符串的第一个字符处
例如, 一段起始地址为1000的内存空间, 则1000~1003这四个字节存放字符串的长度, 1004开始才是字符串的真正内容, BSTR变量应指向1004而不是1000
wchar_t *用于保存UTF-16编码格式的字符串, printf用%ls输出(不能有中文, 否则会出错)
要输出含有中文的wchar_t *字符串, 请使用WriteConsoleW函数
char *可以用来保存任意编码格式的字符串, 但只有ANSI格式才能使用printf的%s正确显示出来
在简体中文版操作系统下, ANSI就是GBK编码
MultiByteToWideChar函数可以将char *字符串转换为wchar_t *字符串
WideCharToMultiByte函数可以将wchar_t *字符串转换为char *t字符串
SysAllocString函数可以将wchar_t *字符串转换为BSTR字符串
(3) IXMLDOMDocument接口: https://msdn.microsoft.com/en-us/library/windows/desktop/dd892951(v=vs.85).aspx
(4) 组件对象模型COM:
https://msdn.microsoft.com/en-us/library/windows/desktop/ff485848(v=vs.85).aspx
https://msdn.microsoft.com/en-us/library/windows/desktop/ms680573(v=vs.85).aspx
(5) Windows窗口程序: https://msdn.microsoft.com/en-us/library/windows/desktop/ff381409(v=vs.85).aspx
*/
// 显示元素节点的属性值 (元素节点是一种节点)
void display_attribute(IXMLDOMElement *elem, const wchar_t *name, bool intval = false)
{
BSTR bstr; // 表示一个字符串
int num;
VARIANT variant; // 表示一个弱类型的变量
bstr = SysAllocString(name); // 必须用SysAllocString函数把wchar_t *字符串转换成BSTR字符串
elem->getAttribute(bstr, &variant);
SysFreeString(bstr); // 使用完字符串后必须释放
printf("[Attribute] name=%ls, value=%ls", name, variant.bstrVal); // BSTR和wchar_t *字符串都用%ls输出
if (intval)
{
num = _wtoi(variant.bstrVal); // 转换为整形
printf(", 2*value=%d", 2 * num);
}
printf("\n");
SysFreeString(variant.bstrVal); // 保存在Variant中的BSTR也必须释放掉
}
// 显示节点名称
void display_nodename(IXMLDOMNode *node)
{
BSTR bstr;
node->get_nodeName(&bstr);
printf("[Node] name=%ls\n", bstr); // 使用%ls打印BSTR字符串内容
SysFreeString(bstr); // 使用完字符串后必须释放
}
// 显示节点中的文本内容 (方法一)
/*
void display_content(IXMLDOMNode *node)
{
BSTR text;
node->get_text(&text);
printf("[Text] %ls\n", text);
SysFreeString(text);
}
*/
// 显示节点中的文本内容 (方法二)
// 文本内容是文本节点, 是node节点下的子节点
void display_content(IXMLDOMNode *node)
{
IXMLDOMNode *child;
VARIANT value;
node->get_firstChild(&child); // 获取文本节点
child->get_nodeValue(&value); // 得到文本节点的内容
printf("[Text] %ls\n", value.bstrVal);
SysFreeString(value.bstrVal);
child->Release();
}
// 获取节点中的XML文本内容
void display_inner_xml(IXMLDOMNode *node)
{
BSTR bstr;
node->get_xml(&bstr);
printf("[InnerXML] %ls\n", bstr);
SysFreeString(bstr);
}
void read_xml(IXMLDOMDocument *pDoc)
{
// 根节点
IXMLDOMElement *root;
pDoc->get_documentElement(&root);
display_nodename(root);
display_attribute(root, L"id", true);
display_inner_xml(root);
printf("\n");
// 根节点下的子节点
IXMLDOMNodeList *list;
long i, len;
root->get_childNodes(&list);
list->get_length(&len);
for (i = 0; i < len; i++)
{
IXMLDOMNode *item;
list->get_item(i, &item);
display_nodename(item);
display_content(item);
// 只有元素节点才有属性节点, 所以获取属性前要进行类型转换, 把node变为element node
IXMLDOMElement *elem;
item->QueryInterface(&elem);
display_attribute(elem, L"name");
elem->Release();
item->Release();
printf("\n");
}
list->Release();
root->Release();
}
// 打开XML文件
void open_xml(const wchar_t *name)
{
HRESULT hr;
IXMLDOMDocument *pDoc;
hr = CoCreateInstance(CLSID_DOMDocument60, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pDoc));
if (SUCCEEDED(hr))
{
VARIANT filename;
VARIANT_BOOL flag;
filename.bstrVal = SysAllocString(name); // 将wchar_t *转换为BSTR
filename.vt = VT_BSTR;
pDoc->load(filename, &flag);
SysFreeString(filename.bstrVal);
if (flag == VARIANT_TRUE)
{
printf("Load succeeded!\n");
read_xml(pDoc);
}
else
printf("Load failed!\n");
pDoc->Release();
}
}
int main(void)
{
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); // 初始化COM组件对象模型
open_xml(L"data.xml");
CoUninitialize();
return 0;
}
【XML文档】
文档的标签之间最好不要用回车换行和空格,否则很容易被误识别为文本节点。
abcd efgh
【程序运行结果】
Load succeeded!
[Node] name=data
[Attribute] name=id, value=105, 2*value=210
[InnerXML] abcd efgh
[Node] name=book
[Text] abcd
[Attribute] name=name, value=haha
[Node] name=book
[Text] efgh
[Attribute] name=name, value=hoho
Press any key to continue . . .