CMarkup与tinyXml直接解析XML字符串

以前都是用CMarkup这个简便的开源码直接解析字符串形式的XML。一般都是先存入一个文件,然后从文件中load(CMarkup可以直接从文件中获取xml档到它自己内部的一个字符串中)。多做了I/O操作,效率不高。今天才知道tinyxml原来也可以直接解析字符串形式的xml。

CMarkup xml;

CString str;

xml.SetDoc(str);

 

tinyXml也可以直接解析XML字符串,方式如下:

// directly parsing string with tinyxml   

const char* content = "";   

TiXmlDocument *doc = new TiXmlDocument();    

doc->Parse(content);   

if (&doc == NULL)   

 cout << "doc == NULL" << endl;     

TiXmlHandle docHandle(doc);   

TiXmlNode * root = docHandle.FirstChild("root").ToElement();   

TiXmlNode * elemNode = root->FirstChild( "elem" );   

TiXmlElement * elemElem = elemNode->ToElement();   

cout << elemElem->Attribute("name");  

 

结果:aaa

 

如何把用TiXmlDocument读取的内存中的xml存到string中?

需要下载最新版本的tinyxml,然后使用以下代码
//TiXmlPrinter是继承TiXmlVisitor
// Accept函数原型Accept( TiXmlVisitor* visitor )
TiXmlPrinter printer;
//TiXmlDocument,TiXmlElement,TiXmlText,TiXmlDeclaration,TiXmlNode 都有Accept 函数,若是TiXmlElement对象调用Accept可以把该元素打印到一个字符串中
doc->Accept(&printer);
strResult.Format("%s", printer.CStr());
这个代码是输出到CString的,楼主修改下改为string就OK啦
 
 
tinyxml也是可以直接对xml字串解析的

 const char* content = REGEIST_DEVICETYPE;
 TiXmlDocument* doc = new TiXmlDocument();
 doc->Parse(content);
 if(NULL == doc)
 {
  cout << "doc == NULL" << endl;
  return 0;
 }

 TiXmlHandle docHandle(doc);
 TiXmlElement* pElemRoot = docHandle.FirstChildElement("mdpc").ToElement();
 TiXmlElement* pElemData = pElemRoot->FirstChildElement("data");

 
tinyxml中对于属性值的修改和text文本的修改

//文本的修改

TiXmlNode* node = daysElement->FirstChild();

TiXmlText newText(“20”);

 daysElement->ReplaceChild( node,newText );

//属性添加 或修改
tixmlElement->SetAttribute("screening", "123");
//保存到文件(记得保存)
myDocument->SaveFile("user.xml");
备注:
在使用tinyxml时,可能会new好多对象,但tinyxml的每个对象,在被释放析构时,会将它下面的所有节点都释放点,如TiXmlDocument 文档对象,我们只需要delete doc即可,若是你还delete pElemRoot; delete pElemData,则在运行时会被二次释放报错。
 

尽量不要在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标记字节, 虽然它不是标准, 但普遍使用).当然还是那句话 ---- 尽量不使用中文和其它非英文字符, 除非迫不得已.

你可能感兴趣的:(工具)