• windwos自带的 一个xml库 MSXML 兼容宽字符


     1 #include <iostream>
     2 #include <tchar.h>
     3 
     4 #import <msxml3.dll>
     5 
     6 //节点处理函数
     7 void ProcessNode(MSXML2::IXMLDOMNodePtr spNode)
     8 {
     9 std::cout << "nodeName: " << spNode->nodeName;
    10 if (spNode->nodeType == NODE_ATTRIBUTE || spNode->nodeType == NODE_TEXT)
    11 std::cout << "	nodeValue: " << _bstr_t(spNode->nodeValue);
    12 std::cout << std::endl;
    13 
    14 if (spNode->nodeType == NODE_ELEMENT)
    15 {
    16 MSXML2::IXMLDOMNamedNodeMapPtr spNameNodeMap = spNode->attributes;
    17 for (long i = 0; i != spNameNodeMap->length; ++i) //遍历节点属性
    18 ProcessNode(spNameNodeMap->item[i]);
    19 
    20 MSXML2::IXMLDOMNodeListPtr spNodeList = spNode->childNodes;
    21 for (long i = 0; i != spNodeList->length; ++i) //遍历子节点
    22 ProcessNode(spNodeList->item[i]);
    23 }
    24 }
    25 
    26 int _tmain(int argc, _TCHAR* argv[])
    27 {
    28 CoInitialize(NULL);
    29 //读取XML
    30 MSXML2::IXMLDOMDocumentPtr spXMLDoc;
    31 spXMLDoc.CreateInstance(__uuidof(MSXML2::DOMDocument30));
    32 spXMLDoc->load(L"stocks.xml");
    33 MSXML2::IXMLDOMElementPtr spRoot = spXMLDoc->documentElement; //根节点
    34 MSXML2::IXMLDOMNodeListPtr spNodeList = spRoot->childNodes;
    35 for (long i = 0; i != spNodeList->length; ++i) //遍历子节点
    36 ProcessNode(spNodeList->item[i]);
    37 
    38 //写入XML
    39 spRoot->selectSingleNode(L"/root/node1")->text = L"newText";
    40 spRoot->selectSingleNode(L"/root/node2/childnode1/@attrib1")->nodeValue = L"newValue";
    41 MSXML2::IXMLDOMNodePtr spNewNode = spRoot->selectSingleNode(L"/root/node2")->appendChild(
    42 spXMLDoc->createNode(_variant_t(NODE_ELEMENT), L"childnode3", L"")
    43 ); //给node2创建新子节点childnode3
    44 spNewNode->text = L"childtext2";
    45 MSXML2::IXMLDOMElementPtr spEle = spNewNode;
    46 spEle->setAttribute(L"attrib1", _variant_t(L"value1")); //添加新属性
    47 spXMLDoc->save(_variant_t(L"stocks.xml"));
    48 
    49 spNewNode.Release();
    50 spEle.Release();
    51 spNodeList.Release();
    52 spRoot.Release();
    53 spXMLDoc.Release();
    54 CoUninitialize();
    55 
    56 system("pause");
    57 return 0;
    58 }

    MFC
    MFC里可以直接使用DOM,不需要手动添加额外的头文件,只需要在CWinApp::InitInstance()里调用CoInitialize(NULL)初始化COM,在CWinApp::ExitInstance里调用CoUninitialize()释放COM就行了。

     1 //读取XML
     2 CComPtr<IXMLDOMDocument> spDoc; //DOM
     3 spDoc.CoCreateInstance(CLSID_DOMDocument);
     4 VARIANT_BOOL vb;
     5 spDoc->load(CComVariant(OLESTR("stocks.xml")), &vb); //加载XML文件
     6 CComPtr<IXMLDOMElement> spRootEle;
     7 spDoc->get_documentElement(&spRootEle); //根节点
     8 CComPtr<IXMLDOMNodeList> spNodeList;
     9 spRootEle->get_childNodes(&spNodeList); //子节点列表
    10 long nLen;
    11 spNodeList->get_length(&nLen); //子节点数
    12 for (long i = 0; i != nLen; ++i) //遍历子节点
    13 {
    14 CComPtr<IXMLDOMNode> spNode;
    15 spNodeList->get_item(i, &spNode);
    16 ProcessNode(spNode); //节点处理函数
    17 }
    18 
    19 //写入XML
    20 CComPtr<IXMLDOMNode> spNode;
    21 spRootEle->selectSingleNode(OLESTR("/root/node1"), &spNode);
    22 spNode->put_text(OLESTR("newText")); //写入text
    23 spRootEle->selectSingleNode(OLESTR("/root/node2/childnode1/@attrib1"), &spNode);
    24 spNode->put_nodeValue(CComVariant(OLESTR("newValue"))); //写入value
    25 CComPtr<IXMLDOMNode> spNewNode;
    26 spDoc->createNode(CComVariant(NODE_ELEMENT), OLESTR("childnode3"), OLESTR(""), &spNewNode); //创建新节点
    27 spRootEle->selectSingleNode(OLESTR("/root/node2"), &spNode);
    28 spNode->appendChild(spNewNode, &spNewNode); //将新节点加为node2的子节点
    29 spNewNode->put_text(OLESTR("childtext2")); //写入新节点text
    30 CComQIPtr<IXMLDOMElement> spEle = spNewNode; //注意这里使用CComQIPtr
    31 spEle->setAttribute(OLESTR("attrib1"), CComVariant(OLESTR("value1")));//给新节点添加属性
    32 spDoc->save(CComVariant(OLESTR("stocks.xml")));
    33 
    34 //节点处理函数
    35 void ProcessNode(CComPtr<IXMLDOMNode>& spNode)
    36 {
    37 CComBSTR bsNodeName;
    38 spNode->get_nodeName(&bsNodeName); //节点名
    39 AfxMessageBox(COLE2CT(bsNodeName));
    40 CComVariant varVal;
    41 spNode->get_nodeValue(&varVal); //节点值
    42 AfxMessageBox(COLE2CT(varVal.bstrVal));
    43 
    44 DOMNodeType eNodeType;
    45 spNode->get_nodeType(&eNodeType);
    46 if (eNodeType == NODE_ELEMENT) //只有NODE_ELEMENT类型才能包含有属性和子节点
    47 {
    48 //递归遍历节点属性
    49 CComPtr<IXMLDOMNamedNodeMap> spNameNodeMap;
    50 spNode->get_attributes(&spNameNodeMap);
    51 long nLength;
    52 spNameNodeMap->get_length(&nLength);
    53 for (long i = 0; i != nLength; ++i)
    54 {
    55 CComPtr<IXMLDOMNode> spNodeAttrib; //注意属性也是一个IXMLDOMNode
    56 spNameNodeMap->get_item(i, &spNodeAttrib);
    57 ProcessNode(spNodeAttrib);
    58 }
    59 
    60 //递归遍历子节点
    61 CComPtr<IXMLDOMNodeList> spNodeList;
    62 spNode->get_childNodes(&spNodeList);
    63 spNodeList->get_length(&nLength);
    64 for (long i = 0; i != nLength; ++i)
    65 {
    66 CComPtr<IXMLDOMNode> spChildNode;
    67 spNodeList->get_item(i, &spChildNode);
    68 ProcessNode(spChildNode);
    69 }
    70 }
    71 }

    对于<tag>text</tag>这样的节点,get_nodeValue会得到空,要得到"text"的话可以遍历子节点(只有一个子节点,它的nodeName为"#text",nodeType为NODE_TEXT,nodeValue就是"text");也可以用get_text直接得到"text",但是对于这样的节点<tag>text<childtag>childtext</childtag></tag>,get_text会同时得到"text"和"childtext",不过这样的节点应该是不允许的。
    DOM里使用的字符串(BSTR)都是OLESTR类型,默认情况下OLESTR是Unicode字符,MFC里可以用COLE2CT把LPCOLESTR转换为LPCTSTR。
    对于自己定义的XML,大多数时候不需要遍历,可以通过调用selectNodes、selectSingleNode指定XPath直接读取某个节点或属性:

     1 CComPtr<IXMLDOMDocument> spDoc; //DOM
     2 spDoc.CoCreateInstance(CLSID_DOMDocument);
     3 VARIANT_BOOL vb;
     4 spDoc->load(CComVariant(OLESTR("stocks.xml")), &vb); //加载XML文件
     5 CComPtr<IXMLDOMElement> spRootEle;
     6 spDoc->get_documentElement(&spRootEle); //根节点
     7 
     8 CComPtr<IXMLDOMNodeList> spNodeList;
     9 CComPtr<IXMLDOMNode> spNode;
    10 spRootEle->selectNodes(OLESTR("/root/node2/*"), &spNodeList); //得到node2下的所有子节点
    11 spRootEle->selectSingleNode(OLESTR("/root/node2/childnode1/@attrib1"), &spNode); //得到childnode1的attrib1属性

    XPath的语法可以参考XML文档或MSDN。

    最后放上xml 

    <?xml version="1.0" encoding="utf-8"?>
    <root>
    <node1>text1</node1>
    <node2>
    <childnode1 attrib1="value1" attrib2="value2"/>
    <childnode2 attrib1="value1" attrib2="value2">childtext1</childnode2>
    </node2>
    </root>
  • 相关阅读:
    linux获取日志指定行数范围内的内容
    python解决open()函数、xlrd.open_workbook()函数文件名包含中文,sheet名包含中文报错的问题
    robot framework添加库注意事项
    robot framework取出列表子元素
    Vue 及框架响应式系统原理
    响应式布局和自适应布局的不同
    前端综合学习笔记---异步、ES6/7、Module、Promise同步 vs 异步
    前端综合学习笔记---变量类型、原型链、作用域和闭包
    doT.js模板引擎及基础原理
    Spring Boot入门第五天:使用JSP
  • 原文地址:https://www.cnblogs.com/youyaoqi/p/15331613.html
Copyright © 2020-2023  润新知