浅谈使用Rapidxml 库遇到的问题和分析过程(分享)
|
副问题[/!--empirenews.page--]
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,"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),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,indent);
break;
// Element
case node_element:
out = print_element_node(out,indent);
break;
// Data
case node_data:
out = print_data_node(out,indent);
break;
// CDATA
case node_cdata:
out = print_cdata_node(out,indent);
break;
// Declaration
case node_declaration:
out = print_declaration_node(out,indent);
break;
// Comment
case node_comment:
out = print_comment_node(out,indent);
break;
// Doctype
case node_doctype:
out = print_doctype_node(out,indent);
break;
// Pi
case node_pi:
out = print_pi_node(out,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;
}
(编辑:湖南网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |

