Tinyxml2可以.net 对xml 重新排序文件进行排序吗

// XMLT01.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include &iostream&#include "tinyxml2.h"
using namespace TinyXml2;
void ReadTest01XML(){&XMLD&doc.LoadFile("Test01.xml");&const char * content = doc.FirstChildElement("test")-&GetText();&printf("%s\n",content);}
void Printfln(const char * content, const char * name = "",const int n = 0, const char * notEqual1 = "", const char * notEqual2 = NULL){&for(int i = 0; i & i++)&{&&printf("&&& ");&}&if(content != notEqual1 && content != notEqual2)&{&&printf("%s: %s\n",name,content);&}&else&{&&printf("%s: \n",name);&}}
void ReadXML(const XMLElement *root){&if(NULL == root)&{&&&}
&static int flag = 0;
&const char * rootName = NULL;&const char * rootContent = NULL;&const XMLAttribute& * rootAttribute = NULL;&const char * rootAttributeName = NULL;&const char * rootAttributeValue = NULL;&rootName = root-&Name();&rootContent = root-&GetText();&rootAttribute = root-&FirstAttribute();&if(NULL != rootAttribute)&{&&rootAttributeName = rootAttribute-&Name();&&rootAttributeValue = rootAttribute-&Value();&}&Printfln(rootContent,rootName,flag);&Printfln(rootAttributeValue,rootAttributeName,flag);
&const XMLElement *child = root-&FirstChildElement();&if(NULL != child)&{&&flag++;&&ReadXML(child);&}
&const XMLElement * nextSibling = root-&NextSiblingElement();&if(NULL != nextSibling)&{&&ReadXML(nextSibling);&}&else&{&&flag--;&&&}}
void ReadTest02XML(){&XMLD&doc.LoadFile("Test02.xml");&const XMLElement *root = doc.RootElement();
&ReadXML(root);
&system("pause");}
int _tmain(int argc, _TCHAR* argv[]){&ReadTest01XML();&ReadTest02XML();&return 0;}
阅读(...) 评论()没有更多推荐了,
不良信息举报
举报内容:
TinyXML2 学习
举报原因:
原文地址:
原因补充:
最多只允许输入30个字
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!参考:http://www.cnblogs.com/hgwang/p/5833638.html
TinyXML用法小结
1.&&&&& 介绍
Tinyxml的官方网址:
官方介绍文档:
在TinyXML中,根据XML的各种元素来定义了一些类:
TiXmlBase:整个TinyXML模型的基类。
TiXmlAttribute:对应于XML中的元素的属性。
TiXmlNode:对应于DOM结构中的节点。
TiXmlComment:对应于XML中的注释
TiXmlDeclaration:对应于XML中的申明部分,即&?versiong="1.0" ?&。
TiXmlDocument:对应于XML的整个文档。
TiXmlElement:对应于XML的元素。
TiXmlText:对应于XML的文字部分
TiXmlUnknown:对应于XML的未知部分。
TiXmlHandler:定义了针对XML的一些操作。
根据下图来说明常用的类对应的文本格式:
&?xml version="1.0" ?& //TiXmlDeclaration,声明
//TiXmlElement,元素
&!-- Settings for MyApp --&//TiXmlComment,注释
&Messages&//TiXmlElement,元素
&Welcome&Welcome to MyApp&/Welcome&
//&Welcome&是元素TiXmlElement ,“Welcome to MyApp”是TiXmlText,文本
&Farewell&Thank you for using MyApp&/Farewell&//同上
&/Messages&
&Windows&//TiXmlElement,元素
&Window name="MainFrame" x="5" y="15" w="400" h="250" /&
// Window是元素TiXmlElement ,name、x、y、h是TiXmlAttribute
&/Windows&
&Connection ip="192.168.0.1" timeout="123.456000" /&
& & & TinyXML是个解析库,主要由DOM模型类(TiXmlBase、TiXmlNode、TiXmlAttribute、TiXmlComment、TiXmlDeclaration、TiXmlElement、TiXmlText、TiXmlUnknown)和操作类(TiXmlHandler)构成。它由两个头文件(.h文件)和四个CPP文件(.cpp文件)构成,用的时候,只要将(tinyxml.h、tinystr.h、tinystr.cpp、tinyxml.cpp、tinyxmlerror.cpp、tinyxmlparser.cpp)导入工程就可以用它的东西了。如果需要,可以将它做成自己的DLL来调用。
注意,TiXmlBase 是TiXmlNode的基类,TiXmlNode是TiXmlElement、TiXmlComment、TiXmlText、TiXmlDeclaration、TiXmlUnknown、TiXmlDocument的基类。
2.&&&&& TinyXML配置
在stdafx.h头文件中增加头文件引用#include "tinyxml/tinyxml.h"
在工程设置中加入lib引用库
在stdafx.h中加入动态库引用
#ifdef _DEBUG
#pragma comment(lib,"TinyXMLD.lib")
#pragma comment(lib,"TinyXML.lib")
3.&&&&& TinyXML读取和保存文件
3.1 读取xml文件
TiXmlDocument lconfigXML;
if( !lconfigXML.LoadFile( strXmlFile.c_str() ) )
3.2 读取xml参数
TiXmlDocument lActionXML;
lActionXML.Parse(strRmcpParam.c_str());
if(lActionXML.Error())
strErr = "输入参数不是标准的xml格式";
3.3 保存xml参数到文本
TiXmlDocument tyD
tyDoc.SaveFile(m_strFilePath);
3.4 保存xml参数到临时变量
TiXmlDocument tyD
tyDoc.Accept(&printer);
std::string devParam = std::string(printer.CStr());
4.&&&&& TinyXML增删改查
创建一个如1中的xml文件代码
void write_app_settings_doc( )
TiXmlElement*
TiXmlDeclaration* decl = new TiXmlDeclaration( "1.0", "", "" );
doc.LinkEndChild( decl );
TiXmlElement * root = new TiXmlElement( "MyApp" );
doc.LinkEndChild( root );
TiXmlComment * comment = new TiXmlComment();
comment-&SetValue(" Settings for MyApp " );
root-&LinkEndChild( comment );
TiXmlElement * msgs = new TiXmlElement( "Messages" );
root-&LinkEndChild( msgs );
msg = new TiXmlElement( "Welcome" );
msg-&LinkEndChild( new TiXmlText( "Welcome to MyApp" ));
msgs-&LinkEndChild( msg );
msg = new TiXmlElement( "Farewell" );
msg-&LinkEndChild( new TiXmlText( "Thank you for using MyApp" ));
msgs-&LinkEndChild( msg );
TiXmlElement * windows = new TiXmlElement( "Windows" );
root-&LinkEndChild( windows );
TiXmlElement *
window = new TiXmlElement( "Window" );
windows-&LinkEndChild( window );
window-&SetAttribute("name", "MainFrame");
window-&SetAttribute("x", 5);
window-&SetAttribute("y", 15);
window-&SetAttribute("w", 400);
window-&SetAttribute("h", 250);
TiXmlElement * cxn = new TiXmlElement( "Connection" );
root-&LinkEndChild( cxn );
cxn-&SetAttribute("ip", "192.168.0.1");
cxn-&SetDoubleAttribute("timeout", 123.456); // floating point attrib
dump_to_stdout( &doc );
doc.SaveFile( "appsettings.xml" );
在节点最后插入新节点
TiXmlNode* LinkEndChild( TiXmlNode* addThis );
在节点后 前/后 插入新节点
TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis );
TiXmlNode* InsertAfterChild(
TiXmlNode* afterThis, const TiXmlNode& addThis );
删除某个节点, TiXmlNode是TiXmlElement、TiXmlComment、TiXmlText、TiXmlDeclaration、TiXmlUnknown、TiXmlDocument的基类
node.Clear();
从A节点上移除子节点B
TiXmlNode nodeA;
nodeA. RemoveChild( TiXmlNode* removeThis );
从元素A上移除名字为B的属性
TiXmlAttribute attrA;
attrA. RemoveAttribute( const char * name );
查找内容为&mfid val="1234" /&,现需要将1234改成其他值
TiXmlNode* lpnode = NULL;
lpnode = tixml.RootElement()-&IterateChildren("mfid",lpnode);
TiXmlAttribute* tiattr = lpnode-&ToElement()-&FirstAttribute();
//找到mfid节点,获取第一个属性值。注意,如果有多个属性值,需要判断哪个属性值是需要的
tiattr-&SetValue(mfid.c_str());
替换一个节点
TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis );&
获取link节点
const TiXmlNode* lpItemNode = NULL;//初始化
lpItemNode = lconfigXML.RootElement()-&IterateChildren("link", lpItemNode);
if (lpItemNode == NULL)
//Can not find &link&
获取link节点中的type属性值
std::string strType = lpItemNode-&ToElement()-&Attribute("type");
const TiXmlNode* lpMapNode = NULL; //初始化
lpMapNode = lconfigXML.RootElement()-&IterateChildren("node", lpMapNode);
if (lpMapNode)
rms::CStationM
const TiXmlNode* lpItemNode = NULL ;
while(lpItemNode = lpMapNode-&IterateChildren("item",lpItemNode))
string str = lpItemNode-&ToElement()-&Attribute("ABC");
遍历元素属性
TiXmlAttribute* pAttr = NULL;
for (pAttr = pNode-&FirstAttribute(); pA pAttr = pAttr-&Next())
节点的下一个兄弟节点
const TiXmlNode* NextSibling()
元素的下一个元素
const TiXmlElement* NextSiblingElement()
属性的下一个属性
const TiXmlAttribute* Next()
返回值为NULL表示不存在
5.  TinyXml常用操作封装
&  使用TinyXml的时候,经常会遇到两个问题:
  1:TinyXml不检查输入参数,如果参数输入不当,会偶发异常。且该异常不易捕捉。
  2:处理较大规模xml的时候,类似IterateChildren等的语句会出现很多行,重复代码量很大。 为解决以上两个问题,我对TinyXml进行简单封装。对于问题1,定义了几种处理状态,当参数不当或其他问题发生时,会返回对应的错误代码。用GetStatus可解析出该异常。 
1 //tinyxml 宏
2 //N:Node,C:Child node,Cn:Child node's name,An:Attribute name,V:Value(string类型)
3 //D:tixmldocument,P:tixmlprinter,p:param,Pre:previous
4 #ifndef TNXML_COMMON
5 #define TNXML_COMMON
7 #define TNXML_XML_PARAM
8 #define TNXML_XML_FILE
10 #define TNXML_OK
11 #define TNXML_NOT_FIND_NODE
12 #define TNXML_NOT_FIND_ATTR
13 #define TNXML_PARAM_NODE_NULL
14 #define TNXML_PARAM_STR_NULL
15 #define TNXML_PARAM_NOT_XML
16 #define TNXML_OTHER_ERROR
18 class CTNXML
20 public:
//查找节点N下子节点Cn(Pre节点后),用output返回
static int CN(TiXmlNode* N,std::string Cn,TiXmlNode* Pre,TiXmlNode*& output)
if (N == NULL)
return TNXML_PARAM_NODE_NULL;
if (Cn.empty())
return TNXML_PARAM_STR_NULL;
TiXmlNode* node =
N-&IterateChildren(Cn.c_str(),Pre);
return TNXML_OK;
return TNXML_NOT_FIND_NODE;
//查找节点N下属性An的值,用output返回
static int ELE_ATTR_VAL(TiXmlNode* N,std::string An,std::string& output)
if (N == NULL)
return TNXML_PARAM_NODE_NULL;
else if (An.empty())
return TNXML_PARAM_STR_NULL;
if (N-&ToElement()-&Attribute(An.c_str()) == NULL)
return TNXML_NOT_FIND_ATTR;
output = N-&ToElement()-&Attribute(An.c_str());
return TNXML_OK;
//查找节点N下子节点Cn(Pre节点后),用output返回Cn下属性An的值
static int ITER_ELE_ATTR_VAL(TiXmlNode* N,std::string Cn,TiXmlNode* Pre,std::string An,std::string& output)
TiXmlNode* node = NULL;
int res = CN(N,Cn,Pre,node);
if ( res == TNXML_OK)
res = ELE_ATTR_VAL(node,An,str);
if (res == TNXML_OK)
return TNXML_OK;
//设置节点N下属性An的值为V
static int ELE_SET_ATTR(TiXmlNode* N,std::string An,std::string V)
if (N == NULL)
return TNXML_PARAM_NODE_NULL;
else if (An.empty())
return TNXML_PARAM_STR_NULL;
N-&ToElement()-&SetAttribute(An.c_str(),V.c_str());
return TNXML_OK;
//设置节点N下子节点Cn(Pre后)属性An的值为V
static int ITER_ELE_SET_ATTR_VAL(TiXmlNode* N,std::string Cn,TiXmlNode* Pre,std::string An,std::string V)
TiXmlNode* node = NULL;
int res = CN(N,Cn,Pre,node);
if ( res == TNXML_OK)
res = ELE_SET_ATTR(node,An,V);
//读取xml参数(字符串),返回根节点
static int PARAM_TO_ROOTELE(std::string& str,TiXmlElement* output)
if (str.empty())
return TNXML_PARAM_STR_NULL;
TiXmlDocument* D = new TiXmlD
if (D-&Parse(str.c_str()))
D-&RootElement();
if (output)
return TNXML_OK;
return TNXML_PARAM_NOT_XML;
return TNXML_PARAM_NOT_XML;
//读取xml参数(文件地址),返回根节点
static int DOC_TO_ROOTELE(std::string& str,TiXmlElement* output)
if (str.empty())
return TNXML_PARAM_STR_NULL;
TiXmlDocument* D = new TiXmlD
if (D-&LoadFile(str.c_str()))
D-&RootElement();
if (output)
return TNXML_OK;
return TNXML_PARAM_NOT_XML;
return TNXML_PARAM_NOT_XML;
//N尾部插入名为Cn的新节点,属性名值An,值V
static int LinkNewNodeWithAttr(TiXmlNode* N,std::string Cn,std::string An,std::string V,TiXmlElement*& C)
if (N == NULL)
return TNXML_PARAM_NODE_NULL;
if (Cn.empty() || An.empty())
return TNXML_PARAM_STR_NULL;
TiXmlElement* ele = new TiXmlElement(Cn);
ele-&SetAttribute(An,V);
N-&LinkEndChild(ele);
return TNXML_OK;
//保存TiXmlDocument文档为字符串
int Doc_To_String(TiXmlDocument& D,std::string& output)
TiXmlPrinter t_
if (D.Accept(&t_printer))
output = std::string(t_printer.CStr());
return TNXML_OK;
return TNXML_OTHER_ERROR;
//保存TiXmlElement文档为字符串
int Ele_To_String(TiXmlElement* N,std::string& output)
if (N==NULL)
return TNXML_PARAM_NODE_NULL;
TiXmlNode* ele = N-&Clone();
doc.LinkEndChild(ele);
return Doc_To_String(doc,output);
return TNXML_OTHER_ERROR;
//保存ele至本地文件
int Ele_To_File(TiXmlElement* N,std::string filepath)
if (N==NULL)
return TNXML_PARAM_NODE_NULL;
TiXmlNode* ele = N-&Clone();
doc.LinkEndChild(ele);
doc.SaveFile(filepath.c_str());
return TNXML_OK;
//将字符串转成小写
static void Xml_To_Lower(std::string& param)
std::transform(param.begin(), param.end(), param.begin(), std::tolower);
//解析以上函数反馈信息
static std::string GetStatus(int index)
switch (index)
case TNXML_OK:
return std::string("OK");
case TNXML_NOT_FIND_NODE:
return std::string("Cannot find node");
case TNXML_NOT_FIND_ATTR:
return std::string("Cannot find attribute");
case TNXML_PARAM_NODE_NULL:
return std::string("Input param node is NULL");
case TNXML_PARAM_STR_NULL:
return std::string("Input param string is NULL");
case TNXML_PARAM_NOT_XML:
return std::string("Input param string is not XML");
case TNXML_OTHER_ERROR:
return std::string("Other errors");
return std::string("Unknown");
301 #endif
& & & 以上是我目前经常用到的处理语句,以后会逐步扩展其他操作语句。
6.&&&&& 一个完整例子
void AppSettings::load(const char* pFilename)
TiXmlDocument doc(pFilename);
if (!doc.LoadFile())
TiXmlHandle hDoc(&doc);
TiXmlElement* pE
TiXmlHandle hRoot(0);
// block: name
pElem=hDoc.FirstChildElement().Element();
// should always have a valid root but handle gracefully if it does
if (!pElem)
m_name=pElem-&Value();
// save this for later
hRoot=TiXmlHandle(pElem);
// block: string table
m_messages.clear(); // trash existing table
pElem=hRoot.FirstChild( "Messages" ).FirstChild().Element();
for( pE pE pElem=pElem-&NextSiblingElement())
const char *pKey=pElem-&Value();
const char *pText=pElem-&GetText();
if (pKey && pText)
m_messages[pKey]=pT
// block: windows
m_windows.clear(); // trash existing list
TiXmlElement* pWindowNode=hRoot.FirstChild( "Windows" ).FirstChild().Element();
for( pWindowN pWindowN pWindowNode=pWindowNode-&NextSiblingElement())
const char *pName=pWindowNode-&Attribute("name");
if (pName) w.name=pN
pWindowNode-&QueryIntAttribute("x", &w.x); // If this fails, original value is left as-is
pWindowNode-&QueryIntAttribute("y", &w.y);
pWindowNode-&QueryIntAttribute("w", &w.w);
pWindowNode-&QueryIntAttribute("hh", &w.h);
m_windows.push_back(w);
// block: connection
pElem=hRoot.FirstChild("Connection").Element();
if (pElem)
m_connection.ip=pElem-&Attribute("ip");
pElem-&QueryDoubleAttribute("timeout",&m_connection.timeout);
阅读(...) 评论()使用TinyXml库值得注意的几个地方
&这两天仔细看了下TinyXml的源代码, 完美地搞清楚了一些网友和我自己的很多疑问.
鉴于TinyXml的实用性, 而且现在不少人在使用, 就决定在此做点有意义的事情 ----
列出使用TinyXml库值得注意的几个地方.
&&&&&关于TinyXml库的介绍网上有很多资料,
大家可以试着搜下, 这里我就不多说了, TinyXml很小巧, 但它提供了非常丰富的接口, 特别适用于存取程序的数据, 如果你使用它,
相信你会感觉到它的灵活的.
TinyXml下载地址:&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&以下几点值得注意哦:
1.new出指针而不见delete.
&&&&&如果你看了TinyXml的文档或者一些网友写的例子程序,
你会发现, 其中new出了很多对象而不见一个delete, 这个问题我当时也感觉特别难以接受, 网上也有各种各样的说法,
有说"nwe出这么多, 内存不泄漏才怪", 有说"TinyXml的指针有自销毁功能"等等, 这些说法都是错误的,
只要你正确的使用TinyXml, 无论你new多少(当然在内存的有效使用范围之内)都不会有内存泄漏,
而且TinyXml的指针根本没有自销毁功能, 可以想像一下,
在C++中一个没有经过任何类的包装的指向堆内存的指针变量怎么可能在它自身的生命结束时管得了它所指向的对象?
那它到底是怎么回事?
&&&&&我们都知道(这里我假设你已经看过TinyXml文档),
TinyXml是利用DOM(文档对象模型)来呈现XML文档的, 在它眼中XML文档就是一棵树,
TiXmlDocument对象就是这棵树的根结点, 在一个完整的文档中, 除了它, 其余结点必须都是它的后代,
所以TinyXml用了一个很巧妙的方法来析构每一个结点所对应的对象 ---- 每个结点的析构任务都委托给了它的父亲,
这样只要保证父亲被正确析构, 或者调用了父亲的Clear函数, 它的所有后代都会被正确的析构,
所以对整个文档来说只要TiXmlDocument对象被正确析构, 那就万无一失了, 这棵树会先从叶子销毁, 一直到树根.
像这种数据结构, 为了保证树的完整性而使用堆内存, 和由它自己管理内存也是理所当然的, 由此便可得到以下几个结论:
&&&&&(1)TiXmlDocument对象最好在栈上创建,
如果在堆上创建了, 那你必须得自己销毁它, 千万不要像别的对象一样new出了就不管了.
&&&&&(2)除了TiXmlDocument对象,
树中的别的结点对象, 必须是堆上创建的, 千万不要把栈上对象的地址链接(LinkEndChild)到树中,
因为栈上对象是不能用delete销毁的, 当然TinyXml也有对栈上对象插入的方法, 以下会说到.
&&&&&(3)除了文档结点,
new出的所有结点对象必须被链接到一个父亲结点上, 才可以不用管对象的delete, 而且必须不能管,
不然有可能整棵树会被破坏而得不到正确的遍历和析构, 如果new出的对象从来没链接到某棵树上, 而且将来也不打算链接,
无论有没有别的结点链接到它身上, 你都必须手动delete它.
&&&&&(4)不要尝试链接已经被别的结点链接过的指针,
很显然, 这会造成无法估量的麻烦, 不用多说, 大家都懂的.
2.Insert vs.
&&&&&当然不是所有人都喜欢new,
可能他们更喜欢像std::vector那样插入元素的副本而不是交给它一个指针, TinyXml也提供了同样的方式插入结点 ----
Insert函数(InsertEndChild, InsertBeforeChild, InsertAfterChild),
因为这些函数插入的是结点的副本(包括所有子结点) ,所以可以传给它栈上或堆上的对象, 但是要注意, 如果传入的是堆上对象,
那还必须手动delete它, 而不像LinkEndChild那样链接了就不能管了, 因为树析构的时候析构的是它的副本, 而不是它.
我更倾向于使用Link + 堆上对象, 而不Insert + 栈上对象, 因为这样可以省去创建副本的运行成本,
除非要插入到具体的位置, 而不是End, 当然也可以修改源代码使Link函数也有这种功能.
3.元素的属性不是普通结点.
&&&&&与文本对象(TiXmlText)不同,
属性对象(TiXmlAttribute)在文档树中不是以普通结点形式存在的, 也不从TiXmlNode类派生,
而是被元素结点的数据成员 ---- 一个TiXmlAttributeSet对象所管理,
这个TiXmlAttributeSet对象持有一个环状的TiXmlAttribute对象链表(具体可以参看源代码),
所以TiXmlElement对象通过调用Child系列函数是无法得到属性的, 相反这件事是通过Attribute系列函数完成的.
访问器(从TiXmlVisitor派生的用户实现的类对象, 一种附加的回调机制,
具体参看源代码)没有针对TiXmlAttribute对象的接口, 而必须在对TiXmlElement对象的实现中处理属性,
因此TiXmlAttribute类也没有Accept虚函数.
4.尽量不要在xml中使用中文.
&&&&&TinyXml只认识UTF-8和ISO
8859-1编码, 而不知GB2312为何物, 但事实上你以GB2312在文档中写入中文, 之后可以正确读取,
而且文档在记事本中打开也能显示正确的中文, 其实这是种巧合, 并不是TinyXml支持GB2312了.
&&&&&这个问题需要解释下,
我已经仔细分析过了, TinyXml的函数有char*类型参数, 而没有wchar_t*类型参数,
所以直接在程序中向文档写入中文必然是GB2312方式(这里是以VC编译器为例的), 这时char*只是指向一块内存块,
跟void*一样, 这块内存只有用GB2312才能正确解释为中文, 因为TinyXml是被设计跨平台的,
所以不要指望它会调用WideCharToMultiByte和MultiByteToWideChar来帮你做转换,
而以GB2312写入的中文在读取时这些中文字符的码值是不变的, 也就是你在准备写入文档时是码值是多少, 读取到程序里的值就是多少,
而把这个值当作GB2312编码时就是原来写文档时的中文字符了, 当把写入的文档在记事本打开时, 由于没有utf-8标记字节0xEF
0xBB 0xBF(TinyXml默认不写入这三个字节, 稍后再说怎么让它写入), 所以记事本把xml文件当作GB2312编码打开,
就阴差阳错地把原本错误的字节以正确的中文字符显示了, 但终究这篇xml文档是utf-8编码的, 那些中文字符本应显示为乱码的,
就这样错误的写入, 错误的读取, 记事本错误的判断, 都加到一起就离奇地没有错误了.
&&&&&但错误还是错误,
有一个办法, 就是在文档头部加上utf-8标记字节0xEF 0xBB 0xBF, 这样记事本就能正确判断文档编码,
正确地以utf-8打开, 正确地把中文显示为乱码.
&&&&&基于这几种错误叠加的现象,
如果你生成的xml文档只用在你自己特定的程序中 而不用在其它软件(比如有时要用别的文本处理软件打开查看内容),
那么在文档中存取中文是完全没有问题的, 但在别的地方以utf-8打开时中文就是乱码.
&&&&&保证所有地方都正确的方法是在写入时和读取时用WideCharToMultiByte和MultiByteToWideChar把GB2312编码的中文字串转换为UTF-8编码的中文字串,
如此, 所有软件都能正确的读取UTF-8编码的中文字符(为了让记事本正确的判断为UTF-8, 可以加上utf-8标记字节,
虽然它不是标准, 但普遍使用).当然还是那句话 ---- 尽量不使用中文和其它非英文字符, 除非迫不得已.
另外我在看源代码时,
有几个地方也发表下自己的想法:
&1.关于explicit关键字
&&&&&tinystr.h第85行&
TIXML_EXPLICIT TiXmlString ( const char * str, size_type len) :
&&&&&(TIXML_EXPLICIT宏的内容是explicit)
explicit关键字的作用是使单参数的构造函数不用作隐式转换, 但这个构造函数有两个参数, 很显然,
它根本就没有发生隐式转换的可能, 也完全没有必要使用explicit关键字.
2.关于成员函数const和非const
&&&&&TinyXml的类库中有许多类的函数有const和非const版本,
为什么非const版本的函数不把函数体重新写一遍而是用const_cast把const函数的const性质转换掉再调用它呢?
其实函数体也就返回数据成员的那一两句而已.
3.关于默认实参
&&&&&有些类的重载成员函数们,
一个函数的参数表和另一个函数的参数表的前面部分完全一致,
为什么不使用默认实参而是参数较少的函数版本调用参数较多的函数版本呢?
4.关于Test项目中的乱码
&&&&&这也是很多人都疑惑的一个问题
---- TinyXml库自带Test项目竟然编译不过, 这个问题的原因很简单, 打开xmltest.cpp文件,
定位到第1141行, 你会发现, 该行和下面几行有乱码, 这又是怎么回事?
&&&&&其实这几行是作者为测试ISO
8859-1编码(一种单字节编码, 编码范围使用了8位的所有取值, 也就是0到0xFF)文档而写, 意图把ISO
8859-1字符串写入文档对象, 再从文档对象读取, 只有用ISO 8859-1编码才能正确解释.
&&&&&但是编译器以GB2312打开cpp文件时遇到这几个字符就发生了奇怪的事情
---- 源码变乱码了. 本来乱码没什么的, 大不了我输出到xml文件也乱码就是了, 但问题是那几个字符不仅使它本身乱,
而且它后面的一个asc2字符也有50%的几率跟着遭殃, 因为我们都知道用GB2312解码字符串时如果第一个字节大于0x7F,
一般情况下会把它和接下来的一个字节当作一个整体字符, 当然这个字符可能显示, 也可能不显示, 无论怎样都不是正确的,
所以你会看到那些字串中有用于xml元素的"&"符号而没有"&"符号, 有的字串甚至都没反引号, 这时不要简单的加上反引号,
虽然语法正确了, 能编译, 但xml语法还没纠正, 调试时会导致文档对象里的断言失败而退出.
另外我还查看了这几个乱码字符的二进制值:
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

我要回帖

更多关于 for xml path 排序 的文章

 

随机推荐