CMarkup与tinyXml直接解析XML字符串
2014-06-25 11:31
246 查看
以前都是用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 = "<root><elem name=/"aaa/"/></root>";
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,则在运行时会被二次释放报错。
这个问题需要解释下, 我已经仔细分析过了, 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标记字节, 虽然它不是标准, 但普遍使用).当然还是那句话 ---- 尽量不使用中文和其它非英文字符, 除非迫不得已.
CMarkup xml;
CString str;
xml.SetDoc(str);
tinyXml也可以直接解析XML字符串,方式如下:
// directly parsing string with tinyxml
const char* content = "<root><elem name=/"aaa/"/></root>";
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标记字节, 虽然它不是标准, 但普遍使用).当然还是那句话 ---- 尽量不使用中文和其它非英文字符, 除非迫不得已.
相关文章推荐
- CMarkup与tinyXml直接解析XML字符串
- CMarkup与tinyXml直接解析XML字符串
- log4j直接在字符串中构建xml以及解析xml
- tinyxml解析内存中的xml字符串
- 使用tinyxml封装或解析xml形式字符串
- 加载并解析 XML 字符串
- wxWidgets利用tinyxml实现xml解析
- java解析xml字符串
- 解析XML字符串与xml文件
- XMLDOM解析XML字符串
- VC解析XML--CMarkup
- TinyXml不写入文件,直接写入字符串的办法 - 好不容易才找到
- 今天遇见的一个问题xml格式的字符串,有办法直接的解析吗
- js 加载并解析XML字符串的代码
- 通过dom4j解析xml字符串
- 使用TinyXML解析XML
- 如何去解析一个xml字符串
- java JDOM解析XML字符串(非XML文档)
- 如何使用TinyXML来解析xml文档:
- 解析XML的利器-TinyXML