浅谈使用Rapidxml 库遇到的问题和分析过程(分享)分享

—-想了解浅谈使用Rapidxml 库遇到的问题和分析过程(分享)分享的全部内容且更多的C语言教程关注

C++解析xml的开源库有很多,在此我就不一一列举了,今天主要说下Rapidxml,我使用这个库也并不是很多,如有错误之处还望大家能够之处,谢谢。

附:

官方链接:http://rapidxml.sourceforge.net/

官方手册:http://rapidxml.sourceforge.net/manual.html

之前有一次用到,碰到了个”坑”,当时时间紧迫并未及时查找,今天再次用到这个库,对这样的”坑”不能踩第二次,因此我决定探个究竟。

先写两段示例:

创建xm:

void CreateXml() { rapidxml::xml_document<> doc; auto nodeDecl = doc.allocate_node(rapidxml::node_declaration); nodeDecl->append_attribute(doc.allocate_attribute(\”version\”, \”1.0\”)); nodeDecl->append_attribute(doc.allocate_attribute(\”encoding\”, \”UTF-8\”)); doc.append_node(nodeDecl);//添加xml声明 auto nodeRoot = doc.allocate_node(rapidxml::node_element, \”Root\”);//创建一个Root节点 nodeRoot->append_node(doc.allocate_node(rapidxml::node_comment, NULL, \”编程语言\”));//添加一个注释内容到Root,注释没有name 所以第二个参数为NULL auto nodeLangrage = doc.allocate_node(rapidxml::node_element, \”language\”, \”This is C language\”);//创建一个language节点 nodeLangrage->append_attribute(doc.allocate_attribute(\”name\”, \”C\”));//添加一个name属性到language nodeRoot->append_node(nodeLangrage); //添加一个language到Root节点 nodeLangrage = doc.allocate_node(rapidxml::node_element, \”language\”, \”This is C++ language\”);//创建一个language节点 nodeLangrage->append_attribute(doc.allocate_attribute(\”name\”, \”C++\”));//添加一个name属性到language nodeRoot->append_node(nodeLangrage); //添加一个language到Root节点 doc.append_node(nodeRoot);//添加Root节点到Document std::string buffer; rapidxml::print(std::back_inserter(buffer), doc, 0); std::ofstream outFile(\”language.xml\”); outFile << buffer; outFile.close(); }

结果:

<?xml version=\”1.0\” encoding=\”UTF-8\”?> <Root> <!–编程语言–> <language name=\”C\”>This is C language</language> <language name=\”C++\”>This is C++ language</language> </Root>

修改xml:

void MotifyXml() { rapidxml::file<> requestFile(\”language.xml\”);//从文件加载xml rapidxml::xml_document<> doc; doc.parse<0>(requestFile.data());//解析xml auto nodeRoot = doc.first_node();//获取第一个节点,也就是Root节点 auto nodeLanguage = nodeRoot->first_node(\”language\”);//获取Root下第一个language节点 nodeLanguage->first_attribute(\”name\”)->value(\”Motify C\”);//修改language节点的name属性为 Motify C std::string buffer; rapidxml::print(std::back_inserter(buffer), doc, 0); std::ofstream outFile(\”MotifyLanguage.xml\”); outFile << buffer; outFile.close(); }

结果:

<Root> <language name=\”Motify C\”>This is C language</language> <language name=\”C++\”>This is C++ language</language> </Root>

由第二个结果得出:

第一个language的name属性确实改成我们所期望的值了,不过不难发现xml的声明和注释都消失了。是怎么回事呢?这个问题也困扰了我一段时间,既然是开源库,那我们跟一下看看他都干了什么,从代码可以看出可疑的地方主要有两处:print和parse,这两个函数均需要提供一个flag,这个flag到底都干了什么呢,从官方给的教程来看 均使用的0,既然最终执行的是print我们就从print开始调试跟踪吧

找到了找到print调用的地方:

template<class OutIt, class Ch> inline OutIt print(OutIt out, const xml_node<Ch> &node, int flags = 0) { return internal::print_node(out, &node, flags, 0); }

继续跟踪:

// Print node template<class OutIt, class Ch> inline OutIt print_node(OutIt out, const xml_node<Ch> *node, int flags, int indent) { // Print proper node type switch (node->type()) { // Document case node_document: out = print_children(out, node, flags, indent); break; // Element case node_element: out = print_element_node(out, node, flags, indent); break; // Data case node_data: out = print_data_node(out, node, flags, indent); break; // CDATA case node_cdata: out = print_cdata_node(out, node, flags, indent); break; // Declaration case node_declaration: out = print_declaration_node(out, node, flags, indent); break; // Comment case node_comment: out = print_comment_node(out, node, flags, indent); break; // Doctype case node_doctype: out = print_doctype_node(out, node, flags, indent); break; // Pi case node_pi: out = print_pi_node(out, node, flags, indent); break; // Unknown default: assert(0); break; } // If indenting not disabled, add line break after node if (!(flags & print_no_indenting)) *out = Ch(\’n\’), ++out; // Return modified iterator return out; }

123下一页

本站无法对海量内容真伪性鉴别,请勿相信本站任何号码,邮件,站外网址等信息,如有需要,请自行甄别。版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至net@163.com举报,一经查实,本站将立刻删除。
(0)
上一篇 2022年8月21日 上午10:22
下一篇 2022年8月21日 上午10:34

相关推荐

发表回复

登录后才能评论