自己在做软件开发时遇到的问题,总结一下和大家分享分享。
我会点boost里ptree的用法,想当然就会使用boost库去操作XML配置文件。我想读取xml的配置文件,当然很简单。
XML配置文件:
<?xml version='1.0' encoding='utf-8' ?>
<root>
<seqs>
<seq name="a" license="1" enable="true"/>
<seq name="b" license="1" enable="true"/>
</seqs>
</root>
用boost读取xml:
using boost::property_tree::ptree;
ptree myPt;
read_xml(sFilePath, myPt, boost::property_tree::xml_parser::trim_whitespace);
ptree &seqsNode = myPt.get_child("root.seqs");
BOOST_FOREACH(const ptree::value_type& vt, seqsNode)
{
std::string seqName = vt.second.get<std::string>("<xmlattr>.SeqName");
vecSeqList.push_back(seqName);
}
前面看起来一切良好,但是我想修改seq的name属性值,其他属性不变,我查了不好资料都没解决,于是放弃boost的ptree方法了。
值得庆幸的是,了解rapidxml之后发现操作起来更为方便,并且boost在找不到节点等情况容易抛出异常。分享一下rapidxml的具体代码。
//create xml using rapidxml
#include <iostream>
#include "rapidxml/rapidxml.hpp"
#include "rapidxml/rapidxml_utils.hpp"
#include "rapidxml/rapidxml_print.hpp"
using namespace rapidxml;
int main()
{
xml_document<> xmlDoc;
xml_node<>* rot = xmlDoc.allocate_node(rapidxml::node_pi,xmlDoc.allocate_string("xml version='1.0' encoding='utf-8'"));
xmlDoc.append_node(rot);
xml_node<>* node = xmlDoc.allocate_node(node_element,"root","information");
xmlDoc.append_node(node);
xml_node<>* seqsNode = xmlDoc.allocate_node(node_element,"seqs",NULL);
node->append_node(seqsNode);
xml_node<>* seqNode = xmlDoc.allocate_node(node_element,"seq",NULL);
seqNode->append_attribute(xmlDoc.allocate_attribute("name","a"));
seqNode->append_attribute(xmlDoc.allocate_attribute("license","1"));
seqNode->append_attribute(xmlDoc.allocate_attribute("enable","true"));
seqsNode->append_node(seqNode);
xml_node<>* seqNode1 = xmlDoc.allocate_node(node_element,"seq",NULL);
seqNode1->append_attribute(xmlDoc.allocate_attribute("name","b"));
seqNode1->append_attribute(xmlDoc.allocate_attribute("license","1"));
seqNode1->append_attribute(xmlDoc.allocate_attribute("enable","true"));
seqsNode->append_node(seqNode1);
std::string text;
rapidxml::print(std::back_inserter(text), xmlDoc, 0);
std::cout<<text<<std::endl;
std::ofstream out("E:/UIMRIS/BRANCHES/uMR_MAIN/MAIN/Features/win32test/XMLFile6.xml");
if (!out.good())
{
std::cout<<"error";
}
out << xmlDoc;
out.close();
std::cout << "seccessful";
getchar();
return 0;
}
//read xml using rapid xml
#include <iostream>
#include "rapidxml/rapidxml.hpp"
#include "rapidxml/rapidxml_utils.hpp"
#include "rapidxml/rapidxml_print.hpp"
#include "boost/property_tree/xml_parser.hpp"
using namespace rapidxml;
int main()
{
file<> fDoc("E:/UIMRIS/BRANCHES/uMR_MAIN/MAIN/Features/win32test/XMLFile6.xml");
std::cout << fDoc.data() << std::endl;
xml_document<> xmlDoc;
xmlDoc.parse<0>(fDoc.data());
xml_node<>* rootNode = xmlDoc.first_node();
xml_node<>* seqsNode = rootNode->first_node();
for (xml_node<>* seqNode = seqsNode->first_node(); seqNode != NULL; seqNode = seqNode->next_sibling())
{
for (xml_attribute<>* attrSeq = seqNode->first_attribute(); attrSeq != NULL; attrSeq = attrSeq->next_attribute())
{
char *val = attrSeq->value();
std::cout << val << std:: endl;
}
}
std::string text;
rapidxml::print(std::back_inserter(text), xmlDoc, 0);
std::cout<<text<<std::endl;
std::ofstream out("E:/UIMRIS/BRANCHES/uMR_MAIN/MAIN/Features/win32test/XMLFile7.xml");
if (!out.good())
{
std::cout<<"error";
}
out << xmlDoc;
out.close();
getchar();
return 0;
}
//set atrribute
#include <iostream>
#include "rapidxml/rapidxml.hpp"
#include "rapidxml/rapidxml_utils.hpp"
#include "rapidxml/rapidxml_print.hpp"
#include "boost/property_tree/xml_parser.hpp"
using namespace rapidxml;
struct SeqStruct
{
std::string seqName[100];
std::string seqLicense[100];
};
int main()
{
SeqStruct seqs;
for(int i = 0; i < 2; i++)
{
seqs.seqName[i] = "li";
seqs.seqLicense[i] = "wu";
}
for(int i = 0; i < 2; i++)
{
std::cout <<seqs.seqName[i];
std::cout <<seqs.seqLicense[i];
std::cout << std::endl;
}
file<> fDoc("E:/UIMRIS/BRANCHES/uMR_MAIN/MAIN/Features/win32test/XMLFile6.xml");
std::cout << fDoc.data() << std::endl;
xml_document<> xmlDoc;
xmlDoc.parse<0>(fDoc.data());
xml_node<>* rootNode = xmlDoc.first_node();
xml_node<>* seqsNode = rootNode->first_node();
int i = 0;
for (xml_node<>* seqNode = seqsNode->first_node(); seqNode != NULL; seqNode = seqNode->next_sibling())
{
bool bFirst = true;
for (xml_attribute<>* attrSeq = seqNode->first_attribute(); attrSeq->next_attribute() != NULL; attrSeq = attrSeq->next_attribute()) //only change 2 attr
{
if (bFirst)
{
attrSeq->value(xmlDoc.allocate_string(seqs.seqName[i].c_str()));
bFirst = false;
}
else
{
attrSeq->value(xmlDoc.allocate_string(seqs.seqLicense[i].c_str()));
bFirst = true;
}
}
i++;
}
std::string text;
rapidxml::print(std::back_inserter(text), xmlDoc, 0);
std::cout<<text<<std::endl;
std::ofstream out("E:/UIMRIS/BRANCHES/uMR_MAIN/MAIN/Features/win32test/XMLFile7.xml");
if (!out.good())
{
std::cout<<"error";
}
out << text;
out.close();
getchar();
return 0;
}
由于比较忙,就没做具体的解释,但是把路径改一下就可以运行了,具体自己可以运行学习学习,其实我自己也在不断学习,有问题可以互相交流。