Skip to content

Instantly share code, notes, and snippets.

@lxfly2000
Last active September 23, 2019 05:53
Show Gist options
  • Save lxfly2000/11db776171a8877b830083a68e7ef3c1 to your computer and use it in GitHub Desktop.
Save lxfly2000/11db776171a8877b830083a68e7ef3c1 to your computer and use it in GitHub Desktop.
Parse XML data using MSXML.
#include<Windows.h>
#include<atlmem.h>
#include<tchar.h>
#include<assert.h>
#include<time.h>
#define HC(e)assert(SUCCEEDED(e))
TCHAR output[4096]{};
LPCTSTR bangumi_xml = LR"(<?xml version="1.0" encoding="utf-8"?>
<bangumi>
<time>2019-8-2 21:36</time>
<data>
<season id="26766"/>
<season id="28007">
<cover>http://i0.hdslb.com/bfs/bangumi/8fa97d1f68517724a0afcb1ca536bfe5b818e0d8.png</cover>
<title>街角魔族</title>
</season>
<season id="28016">
<title>女高中生的虚度日常</title>
<cover>http://i0.hdslb.com/bfs/bangumi/97007f464a9511abdbf8bf938c01dcdbaab151e0.jpg</cover>
</season>
</data>
</bangumi>)";
void XmlMain()
{
VARIANT_BOOL vSuccess;
CComPtr<IXMLDOMDocument>pXmlDoc;//它的自动释放功能会与CoUninitalize起冲突,因此把它放到单独的函数中
CComPtr<IXMLDOMElement>pXmlElem;
CComPtr<IXMLDOMNodeList>pXmlNodes;
CComPtr<IXMLDOMNode>pItem;
//https://blog.csdn.net/zsscy/article/details/6444215
HC(pXmlDoc.CoCreateInstance(CLSID_DOMDocument));
//Variant可以用CComVariant简化
//https://www.cnblogs.com/lingyun1120/archive/2011/11/02/2232709.html
HC(pXmlDoc->loadXML(CComBSTR(bangumi_xml), &vSuccess));//可以用load加载XML文件,save保存文件,且保存后自动转为UTF-8编码(这点好评)
HC(pXmlDoc->get_documentElement(&pXmlElem));
HC(pXmlElem->get_childNodes(&pXmlNodes));
HC(pXmlNodes->get_item(0, &pItem));
CComPtr<IXMLDOMElement>pTimeElem;
HC(pItem->QueryInterface(&pTimeElem));
//读取XML
BSTR s;
HC(pTimeElem->get_text(&s));
lstrcat(output, s);
lstrcat(output, _T("\n"));
SysFreeString(s);
HC(pItem->get_text(&s));
lstrcat(output, _T("跨级获取结果:"));
lstrcat(output, s);
lstrcat(output, _T("\n"));
SysFreeString(s);
//写入XML
time_t t1 = time(NULL);
HC(pTimeElem->setAttribute(CComBSTR(OLESTR("ts")), CComVariant(t1)));
HC(pTimeElem->put_text(CComBSTR(_wctime(&t1))));
CComPtr<IXMLDOMNode>pDataItem;//必须先调用Release才能再次写入,否则要定义新的指针
HC(pXmlNodes->get_item(1, &pDataItem));
CComPtr<IXMLDOMNodeList>pDataNodes;
HC(pDataItem->get_childNodes(&pDataNodes));
long childCount;
HC(pDataNodes->get_length(&childCount));
for (long i = 0; i < childCount; i++)
{
CComPtr<IXMLDOMNode>pSeasonItem;
CComPtr<IXMLDOMNodeList>pSubNodes;
VARIANT v;
VariantInit(&v);
HC(pDataNodes->get_item(i, &pSeasonItem));
CComPtr<IXMLDOMElement>pSeasonElem;
HC(pSeasonItem.QueryInterface(&pSeasonElem));//用QueryInterface转换类型
HC(pSeasonElem->getAttribute(CComBSTR(OLESTR("id")), &v));
lstrcat(output, _T("["));
lstrcat(output, v.bstrVal);
lstrcat(output, _T("]"));
long subChildCount;
HC(pSeasonItem->get_childNodes(&pSubNodes));
HC(pSubNodes->get_length(&subChildCount));
if (subChildCount)
{
lstrcat(output, _T("\n>>>Unordered>>>"));
for (long j = 0; j < subChildCount; j++)
{
CComPtr<IXMLDOMNode>pValueItem;
HC(pSubNodes->get_item(j, &pValueItem));
HC(pValueItem->get_text(&s));
lstrcat(output, s);
SysFreeString(s);
lstrcat(output, _T("\n"));
}
lstrcat(output, _T(">>>Ordered>>>"));
pSubNodes.Release();
HC(pSeasonElem->getElementsByTagName(CComBSTR(OLESTR("title")), &pSubNodes));
CComPtr<IXMLDOMNode>pTitleItem, pCoverItem;
HC(pSubNodes->get_item(0, &pTitleItem));
HC(pTitleItem->get_text(&s));
lstrcat(output, s);
lstrcat(output, _T("\n"));
SysFreeString(s);
pSubNodes.Release();
HC(pSeasonElem->getElementsByTagName(CComBSTR(OLESTR("cover")), &pSubNodes));
HC(pSubNodes->get_item(0, &pCoverItem));
HC(pCoverItem->get_text(&s));
lstrcat(output, s);
SysFreeString(s);
lstrcat(output, _T("\n"));
}
else
{
lstrcat(output, _T("\n"));
}
}
CComPtr<IXMLDOMNodeList>pSelectNodes;
HC(pXmlElem->selectNodes(CComBSTR(OLESTR("/bangumi/data/season[1]/title")), &pSelectNodes));//下标从0开始数
CComPtr<IXMLDOMNode>pSelectNode;
HC(pSelectNodes->get_item(0, &pSelectNode));
HC(pSelectNode->get_text(&s));
lstrcat(output, _T("XPath:\n"));
lstrcat(output, s);
SysFreeString(s);
MessageBox(NULL, output, NULL, NULL);
HC(pXmlDoc->get_xml(&s));
MessageBox(NULL, s, NULL, NULL);
SysFreeString(s);
}
int WINAPI _tWinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ LPTSTR, _In_ int)
{
HC(CoInitialize(NULL));
XmlMain();
CoUninitialize();
return 0;
}
//CODE ONLY
#include "pch.h"
#include "fi.h"
#include <atlmem.h>
#include <MsXml2.h>
int FIBatch_Recognize(const wchar_t *path)
{
if(fi_recognize_file(path))
return -1;
TCHAR o[4096];
int s = ARRAYSIZE(o);
fi_get_result(o, s);
o[s] = 0;
TCHAR xml_path[MAX_PATH];
lstrcpy(xml_path, path);
lstrcpy(wcsrchr(xml_path, '.'), _T(".xml"));
VARIANT_BOOL vSuccess;
CComPtr<IXMLDOMDocument>pXmlDoc,pXmlDocConvert;
CComPtr<IXMLDOMElement>pXmlElem,pXmlConvertElem;
CComPtr<IXMLDOMNodeList>pSelectNodes;
CComPtr<IXMLDOMNode>pItem;
CComPtr<IXMLDOMProcessingInstruction>pXmlHeader;
if (FAILED(pXmlDoc.CoCreateInstance(CLSID_DOMDocument)))
return -1;
pXmlDoc->loadXML(CComBSTR(o), &vSuccess);
pXmlDoc->get_documentElement(&pXmlElem);
pXmlElem->selectNodes(CComBSTR(OLESTR("/FI_Result/ResultList/Result/Field")), &pSelectNodes);
pXmlElem.Release();
if (FAILED(pXmlDocConvert.CoCreateInstance(CLSID_DOMDocument)))
return -1;
pXmlDocConvert->appendChild(pXmlHeader, &pItem);
pItem.Release();
pXmlDocConvert->createElement(CComBSTR(OLESTR("IDCardInfo")),&pXmlConvertElem);
pXmlDocConvert->appendChild(pXmlConvertElem, &pItem);
pItem.Release();
long length;
pSelectNodes->get_length(&length);
for (long i = 0; i < length; i++)
{
CComPtr<IXMLDOMElement>pFieldElem;
pXmlDocConvert->createElement(CComBSTR(OLESTR("Field")), &pFieldElem);
pSelectNodes->get_item(i, &pItem);
pItem->QueryInterface(&pXmlElem);
pItem.Release();
VARIANT v;
VariantInit(&v);
pXmlElem->getAttribute(CComBSTR(OLESTR("key")), &v);
pFieldElem->setAttribute(CComBSTR(OLESTR("name")), v);
pXmlElem->getAttribute(CComBSTR(OLESTR("value")), &v);
pFieldElem->put_text(v.bstrVal);
pXmlConvertElem->appendChild(pFieldElem, &pItem);
pItem.Release();
pXmlElem.Release();
}
CComPtr<IMXWriter> pWriter;
if(FAILED(pWriter.CoCreateInstance(CLSID_MXXMLWriter)))
return -1;
CComPtr<IStream>pStream;
SHCreateStreamOnFile(xml_path, STGM_WRITE | STGM_CREATE, &pStream);
pWriter->put_output(CComVariant(pStream));
pWriter->put_indent(CComVariant(true).boolVal);
pWriter->put_encoding(CComBSTR(OLESTR("UTF-8")));
CComPtr<ISAXXMLReader>pSaxReader;
if(FAILED(pSaxReader.CoCreateInstance(CLSID_SAXXMLReader)))
return -1;
CComPtr<ISAXContentHandler>pHandler;
if(FAILED(pWriter.QueryInterface(&pHandler)))
return -1;
pSaxReader->putContentHandler(pHandler);
pSaxReader->parse(CComVariant(pXmlDocConvert));
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment