/*
作者:刘*
日期:20131217
文件名:ParserXml3.h
vs2008 Debug 工程设置要点:
Xerces3.1=E:\study\myxml\xerces-c-3.1.1-x86-windows-vc-8.0
include:$(Xerces3.1)/include
lib:
文件:xerces-c_3.lib
路径:$(Xerces3.1)/lib
dll:xerces-c_3_1.dll与可执行文件放在同一个目录
lib和dll都选了release版的,能运行成功,好奇怪!
备注:对库2.8,做相同的工程设置,编译链接能成功,但是无法运行;可能工程设置有问题,也有可能lib or dll 文件选取的不对。本文参考了其他文章
*/
#include <stdio.h>
#include "xercesc/dom/DOM.hpp"
#include "xercesc/dom/DOMNode.hpp"
#include "xercesc/dom/DOMDocument.hpp"
#include "xercesc/dom/DOMDocumentType.hpp"
#include "xercesc/dom/DOMElement.hpp"
#include "xercesc/dom/DOMImplementation.hpp"
#include "xercesc/dom/DOMImplementationLS.hpp"
#include "xercesc/dom/DOMNodeIterator.hpp"
#include "xercesc/dom/DOMNodeList.hpp"
#include "xercesc/dom/DOMText.hpp"
#include "xercesc/parsers/XercesDOMParser.hpp"
#include "xercesc/util/XMLUni.hpp"
#include <xercesc/util/OutOfMemoryException.hpp>
#include <xercesc/framework/MemBufFormatTarget.hpp>
#include <xercesc/framework/StdOutFormatTarget.hpp>
#include <xercesc/framework/MemBufInputSource.hpp>
//输出到文件需要这个头文件
#include <xercesc/framework/LocalFileFormatTarget.hpp>
using namespace std;
using namespace XERCES_CPP_NAMESPACE;
#ifdef _DEBUG
#pragma comment( lib, "xerces-c_3D.lib" )
#else
#pragma comment( lib, "xerces-c_3.lib" )
#endif
//一个使用实例 http://blog.youkuaiyun.com/liuchang5/article/details/5775648
//http://blog.youkuaiyun.com/jfkidear/article/details/6863328
#define FILE_NAME "test.xml"
#define _2C XMLString::transcode
#define _X(str) XStr(str).unicodeForm()
class CMyXml
{
public:
CMyXml();
~CMyXml();
bool ParserXML();
bool WriteXML();
void DisHex(char * Str);
private:
XercesDOMParser * m_DOMXmlParser;
};
class XStr
{
public:
XStr(const char* const toTranscode)
{
fUnicodeForm = XMLString::transcode(toTranscode);
}
~XStr()
{
XMLString::release(&fUnicodeForm);
}
const XMLCh* unicodeForm() const
{
return fUnicodeForm;
}
private:
XMLCh* fUnicodeForm;
};
//文件名:ParserXml3.cpp
#include "ParserXml3.h"
#include <iostream>
CMyXml::CMyXml()
{
try
{
// Initialize Xerces-C++ library
XMLPlatformUtils::Initialize();
}
catch(XMLException & excp)
{
char* msg = _2C(excp.getMessage());
printf("XML toolkit initialization error: %s/n", msg);
XMLString::release(&msg);
}
m_DOMXmlParser = new XercesDOMParser();
}
CMyXml::~CMyXml()
{
if (m_DOMXmlParser!=NULL)
{
delete(m_DOMXmlParser);
m_DOMXmlParser = NULL;
}
try
{
XMLPlatformUtils::Terminate();//销毁平台 ,可以修在析构方法中。
}
catch(XMLException& excp)
{
char* msg = _2C(excp.getMessage());
printf("XML toolkit terminate error: %s/n", msg);
XMLString::release(&msg);
}
}
bool CMyXml::ParserXML()
{
m_DOMXmlParser->setValidationScheme(XercesDOMParser::Val_Auto );
m_DOMXmlParser->setDoNamespaces( false );
m_DOMXmlParser->setDoSchema( false );
m_DOMXmlParser->setLoadExternalDTD( false );
m_DOMXmlParser->parse("test.xml");
//得到文件对象
DOMDocument *xmlDoc = m_DOMXmlParser->getDocument();
DOMElement * Root=xmlDoc->getDocumentElement();
//根节点为空
if(!Root) //getDocumentElement用来得到文件根节点
{
delete(m_DOMXmlParser);
m_DOMXmlParser = NULL;
return false;
}
char *sEncoding = _2C(xmlDoc->getXmlEncoding());
char *sVersion = _2C(xmlDoc->getXmlVersion());
//char *sURI = _2C(xmlDoc->getDocumentURI());
char *sRootName = _2C(Root->getNodeName());
if (Root->getNodeType() == DOMNode::ELEMENT_NODE)
{
printf("this is a element node\n");
}
char *sRootVal = _2C(Root->getTextContent());
printf("<xml version='%s' encoding='%s' URI=''>\n",sEncoding,sVersion);
printf("<%s>%s\n",sRootName,sRootVal);
//Root->getFirstChild();
//Root->getLastChild();
DOMNodeList * nodelist=Root->getChildNodes();
int nSize = nodelist->getLength();
printf("child node count =%d\n",nSize);
//得到code 节点 当对应多个 code节点时 则是 nodelist 可用循环遍历,这里只有一个code 就去 item(0)的值 getElementsByTagName 方法很好
DOMNode* xCode = xmlDoc->getElementsByTagName(_2C("CODE"))->item(0);
//取得属性的名称 TEXT
char *aa = _2C(xCode->getAttributes()->item(0)->getNodeName());
//得到属性的值 (每个节点的第一个子节点都是它的值,即便这个值为空,当当前节点是TEXT_NODE属性时 ,才能得到getNodeValue的值) 这是取TEXT 属性的值,取结点的值 方法相同
char* bb = _2C(xCode->getAttributes()->item(0)->getFirstChild()->getNodeValue());
//第二个 属性
char *cc = _2C(xCode->getAttributes()->item(1)->getNodeName());
char* dd = _2C(xCode->getAttributes()->item(1)->getFirstChild()->getNodeValue());
printf(" <CODE %s=%s,%s=%s>\n",aa,bb,cc,dd);
//读取state节点值
DOMNodeList * nodelist2 = xmlDoc->getElementsByTagName(_2C("STATE"));
DOMNode *xState = nodelist2->item(0);//同样只有一个节点,直接取0
char * str_name = _2C(xState->getNodeName()); //可以用来取节点名称
char * str_state = _2C(xState->getFirstChild()->getNodeValue());//_2C 用于字符转换 XMLch转为 string 或者 char*
printf(" <%s=%s> \n",str_name,str_state);
return true;
}
bool CMyXml::WriteXML()
{
char * StudentName[3]={"刘1","李2","刘3"};
char * StudentID[3]={"19870902","19860406","20131028"};
XMLCh str[10];
// Do your actual work with Xerces-C++ here.
_2C("Core", str, 9);
DOMImplementation* impl = DOMImplementationRegistry::getDOMImplementation(str);//DOMImplementation::getImplementation();
DOMLSOutput* output = ((DOMImplementationLS*)impl)->createLSOutput();
DOMLSSerializer* serial = ((DOMImplementationLS*)impl)->createLSSerializer();
//StdOutFormatTarget* target = new StdOutFormatTarget()); //输出到屏幕没有测试过
//MemBufFormatTarget* target = new MemBufFormatTarget(); //输出到屏幕
XMLFormatTarget *target = new LocalFileFormatTarget("write.xml"); //输出到文件
output->setByteStream(target);
DOMDocument * doc = impl->createDocument(0,_X("学生列表"),0);
doc->setXmlStandalone(true);
doc->setXmlVersion(_X("1.0"));
//处理根节点
DOMElement * Root = doc->getDocumentElement();
Root->setAttribute(_2C("id"),_2C("1")); //用_2C同样能处理字符串转换?_X可以不需要
Root->setTextContent(_2C("node1"));
Root->setAttribute(_X("xmlns"), _X("com:cmcc:corporation"));
Root->setAttribute(_X("xmlns:xsi"), _X("http://www.w3.org/2001/XMLSchema-instance"));
Root->setAttribute(_X("xsi:schemaLocation"), _X("com:cmcc:corporation corporation.xsd"));
//添加学生子节点
for (int i=0;i<3;i++)
{
DOMNode * node=doc->createElement(_X("学生"));
Root->appendChild(node);
}
DOMNodeList * nodelist = doc->getElementsByTagName(_X("学生"));
int nSize = nodelist->getLength();
for (int k=0;k<nSize;k++)
{
DOMNode * node = nodelist->item(k);
if (node->getNodeType() == DOMNode::ELEMENT_NODE)
{
DOMElement * ElementNode = (DOMElement*)node;
DOMNode * nodename=doc->createElement(_X("姓名"));
DOMNode * nodeID =doc->createElement(_X("学号"));
nodename->appendChild(doc->createTextNode(_X(StudentName[k])));
nodeID->appendChild(doc->createTextNode(_X(StudentID[k])));
ElementNode->appendChild(nodename);
ElementNode->appendChild(nodeID);
}
}
serial->write(doc, output);
doc->release();
serial->release();
delete target;
return true;
}
void CMyXml::DisHex(char * sName)
{
printf("%s(%d) = 0X",sName,strlen(sName));
for (unsigned int i=0;i<strlen(sName);i++)
{
printf("%X",sName[i]&0xFF);
}
printf("\n");
}
int main()
{
printf("Test how to parser and write a xml file\n");
CMyXml cmyxml;
//测试打印字符串16进制编码的函数
cmyxml.DisHex("3刘33");
cmyxml.ParserXML();
cmyxml.WriteXML();
}
//test.xml
<?xml version="1.0" encoding="GBK" ?>
<NS>Newthon
<CODE TEST="456" VALUE="789">123</CODE>
<RSPTIME>abc</RSPTIME>
<STATE>1</STATE>
<MSG>edg</MSG>
</NS>
作者:刘*
日期:20131217
文件名:ParserXml3.h
vs2008 Debug 工程设置要点:
Xerces3.1=E:\study\myxml\xerces-c-3.1.1-x86-windows-vc-8.0
include:$(Xerces3.1)/include
lib:
文件:xerces-c_3.lib
路径:$(Xerces3.1)/lib
dll:xerces-c_3_1.dll与可执行文件放在同一个目录
lib和dll都选了release版的,能运行成功,好奇怪!
备注:对库2.8,做相同的工程设置,编译链接能成功,但是无法运行;可能工程设置有问题,也有可能lib or dll 文件选取的不对。本文参考了其他文章
*/
#include <stdio.h>
#include "xercesc/dom/DOM.hpp"
#include "xercesc/dom/DOMNode.hpp"
#include "xercesc/dom/DOMDocument.hpp"
#include "xercesc/dom/DOMDocumentType.hpp"
#include "xercesc/dom/DOMElement.hpp"
#include "xercesc/dom/DOMImplementation.hpp"
#include "xercesc/dom/DOMImplementationLS.hpp"
#include "xercesc/dom/DOMNodeIterator.hpp"
#include "xercesc/dom/DOMNodeList.hpp"
#include "xercesc/dom/DOMText.hpp"
#include "xercesc/parsers/XercesDOMParser.hpp"
#include "xercesc/util/XMLUni.hpp"
#include <xercesc/util/OutOfMemoryException.hpp>
#include <xercesc/framework/MemBufFormatTarget.hpp>
#include <xercesc/framework/StdOutFormatTarget.hpp>
#include <xercesc/framework/MemBufInputSource.hpp>
//输出到文件需要这个头文件
#include <xercesc/framework/LocalFileFormatTarget.hpp>
using namespace std;
using namespace XERCES_CPP_NAMESPACE;
#ifdef _DEBUG
#pragma comment( lib, "xerces-c_3D.lib" )
#else
#pragma comment( lib, "xerces-c_3.lib" )
#endif
//一个使用实例 http://blog.youkuaiyun.com/liuchang5/article/details/5775648
//http://blog.youkuaiyun.com/jfkidear/article/details/6863328
#define FILE_NAME "test.xml"
#define _2C XMLString::transcode
#define _X(str) XStr(str).unicodeForm()
class CMyXml
{
public:
CMyXml();
~CMyXml();
bool ParserXML();
bool WriteXML();
void DisHex(char * Str);
private:
XercesDOMParser * m_DOMXmlParser;
};
class XStr
{
public:
XStr(const char* const toTranscode)
{
fUnicodeForm = XMLString::transcode(toTranscode);
}
~XStr()
{
XMLString::release(&fUnicodeForm);
}
const XMLCh* unicodeForm() const
{
return fUnicodeForm;
}
private:
XMLCh* fUnicodeForm;
};
//文件名:ParserXml3.cpp
#include "ParserXml3.h"
#include <iostream>
CMyXml::CMyXml()
{
try
{
// Initialize Xerces-C++ library
XMLPlatformUtils::Initialize();
}
catch(XMLException & excp)
{
char* msg = _2C(excp.getMessage());
printf("XML toolkit initialization error: %s/n", msg);
XMLString::release(&msg);
}
m_DOMXmlParser = new XercesDOMParser();
}
CMyXml::~CMyXml()
{
if (m_DOMXmlParser!=NULL)
{
delete(m_DOMXmlParser);
m_DOMXmlParser = NULL;
}
try
{
XMLPlatformUtils::Terminate();//销毁平台 ,可以修在析构方法中。
}
catch(XMLException& excp)
{
char* msg = _2C(excp.getMessage());
printf("XML toolkit terminate error: %s/n", msg);
XMLString::release(&msg);
}
}
bool CMyXml::ParserXML()
{
m_DOMXmlParser->setValidationScheme(XercesDOMParser::Val_Auto );
m_DOMXmlParser->setDoNamespaces( false );
m_DOMXmlParser->setDoSchema( false );
m_DOMXmlParser->setLoadExternalDTD( false );
m_DOMXmlParser->parse("test.xml");
//得到文件对象
DOMDocument *xmlDoc = m_DOMXmlParser->getDocument();
DOMElement * Root=xmlDoc->getDocumentElement();
//根节点为空
if(!Root) //getDocumentElement用来得到文件根节点
{
delete(m_DOMXmlParser);
m_DOMXmlParser = NULL;
return false;
}
char *sEncoding = _2C(xmlDoc->getXmlEncoding());
char *sVersion = _2C(xmlDoc->getXmlVersion());
//char *sURI = _2C(xmlDoc->getDocumentURI());
char *sRootName = _2C(Root->getNodeName());
if (Root->getNodeType() == DOMNode::ELEMENT_NODE)
{
printf("this is a element node\n");
}
char *sRootVal = _2C(Root->getTextContent());
printf("<xml version='%s' encoding='%s' URI=''>\n",sEncoding,sVersion);
printf("<%s>%s\n",sRootName,sRootVal);
//Root->getFirstChild();
//Root->getLastChild();
DOMNodeList * nodelist=Root->getChildNodes();
int nSize = nodelist->getLength();
printf("child node count =%d\n",nSize);
//得到code 节点 当对应多个 code节点时 则是 nodelist 可用循环遍历,这里只有一个code 就去 item(0)的值 getElementsByTagName 方法很好
DOMNode* xCode = xmlDoc->getElementsByTagName(_2C("CODE"))->item(0);
//取得属性的名称 TEXT
char *aa = _2C(xCode->getAttributes()->item(0)->getNodeName());
//得到属性的值 (每个节点的第一个子节点都是它的值,即便这个值为空,当当前节点是TEXT_NODE属性时 ,才能得到getNodeValue的值) 这是取TEXT 属性的值,取结点的值 方法相同
char* bb = _2C(xCode->getAttributes()->item(0)->getFirstChild()->getNodeValue());
//第二个 属性
char *cc = _2C(xCode->getAttributes()->item(1)->getNodeName());
char* dd = _2C(xCode->getAttributes()->item(1)->getFirstChild()->getNodeValue());
printf(" <CODE %s=%s,%s=%s>\n",aa,bb,cc,dd);
//读取state节点值
DOMNodeList * nodelist2 = xmlDoc->getElementsByTagName(_2C("STATE"));
DOMNode *xState = nodelist2->item(0);//同样只有一个节点,直接取0
char * str_name = _2C(xState->getNodeName()); //可以用来取节点名称
char * str_state = _2C(xState->getFirstChild()->getNodeValue());//_2C 用于字符转换 XMLch转为 string 或者 char*
printf(" <%s=%s> \n",str_name,str_state);
return true;
}
bool CMyXml::WriteXML()
{
char * StudentName[3]={"刘1","李2","刘3"};
char * StudentID[3]={"19870902","19860406","20131028"};
XMLCh str[10];
// Do your actual work with Xerces-C++ here.
_2C("Core", str, 9);
DOMImplementation* impl = DOMImplementationRegistry::getDOMImplementation(str);//DOMImplementation::getImplementation();
DOMLSOutput* output = ((DOMImplementationLS*)impl)->createLSOutput();
DOMLSSerializer* serial = ((DOMImplementationLS*)impl)->createLSSerializer();
//StdOutFormatTarget* target = new StdOutFormatTarget()); //输出到屏幕没有测试过
//MemBufFormatTarget* target = new MemBufFormatTarget(); //输出到屏幕
XMLFormatTarget *target = new LocalFileFormatTarget("write.xml"); //输出到文件
output->setByteStream(target);
DOMDocument * doc = impl->createDocument(0,_X("学生列表"),0);
doc->setXmlStandalone(true);
doc->setXmlVersion(_X("1.0"));
//处理根节点
DOMElement * Root = doc->getDocumentElement();
Root->setAttribute(_2C("id"),_2C("1")); //用_2C同样能处理字符串转换?_X可以不需要
Root->setTextContent(_2C("node1"));
Root->setAttribute(_X("xmlns"), _X("com:cmcc:corporation"));
Root->setAttribute(_X("xmlns:xsi"), _X("http://www.w3.org/2001/XMLSchema-instance"));
Root->setAttribute(_X("xsi:schemaLocation"), _X("com:cmcc:corporation corporation.xsd"));
//添加学生子节点
for (int i=0;i<3;i++)
{
DOMNode * node=doc->createElement(_X("学生"));
Root->appendChild(node);
}
DOMNodeList * nodelist = doc->getElementsByTagName(_X("学生"));
int nSize = nodelist->getLength();
for (int k=0;k<nSize;k++)
{
DOMNode * node = nodelist->item(k);
if (node->getNodeType() == DOMNode::ELEMENT_NODE)
{
DOMElement * ElementNode = (DOMElement*)node;
DOMNode * nodename=doc->createElement(_X("姓名"));
DOMNode * nodeID =doc->createElement(_X("学号"));
nodename->appendChild(doc->createTextNode(_X(StudentName[k])));
nodeID->appendChild(doc->createTextNode(_X(StudentID[k])));
ElementNode->appendChild(nodename);
ElementNode->appendChild(nodeID);
}
}
serial->write(doc, output);
doc->release();
serial->release();
delete target;
return true;
}
void CMyXml::DisHex(char * sName)
{
printf("%s(%d) = 0X",sName,strlen(sName));
for (unsigned int i=0;i<strlen(sName);i++)
{
printf("%X",sName[i]&0xFF);
}
printf("\n");
}
int main()
{
printf("Test how to parser and write a xml file\n");
CMyXml cmyxml;
//测试打印字符串16进制编码的函数
cmyxml.DisHex("3刘33");
cmyxml.ParserXML();
cmyxml.WriteXML();
}
//test.xml
<?xml version="1.0" encoding="GBK" ?>
<NS>Newthon
<CODE TEST="456" VALUE="789">123</CODE>
<RSPTIME>abc</RSPTIME>
<STATE>1</STATE>
<MSG>edg</MSG>
</NS>