如何在c++程序中使用TinyXml2解析xml文件
How to get xml file parsed using TinyXml2 in c++ program?
我第一次使用TinyXml2获取xml文件,如下所示:
<ORDER>
<ITEM>
<SN>132487A-J</SN>
<NAME>crank casing</NAME>
<Person age="12" passed="Yes">Alive</Person>
<QTY>1</QTY>
</ITEM>
</ORDER>
那么,我如何在visual studio中从TinyXml2生成这种类型的xml呢?我在互联网上搜索过,但他们展示的例子非常冗长和复杂,难以理解。所以,请建议我在c++中使用小xml的简单代码片段,可以实现我的目的。
在喷子回答类别中:
注释我已经在这里添加了一个非喷子答案,因为我发现时间使用TinyXML
-
Boost属性树
Live On Coliru
#include <boost/property_tree/ptree.hpp> #include <boost/property_tree/xml_parser.hpp> struct Person { int age; bool passed; enum Condition { Alive, Dead } condition; friend std::ostream& operator<<(std::ostream& os, Condition c) { switch (c) { case Alive : return os << "Alive"; case Dead : return os << "Dead"; } throw "failure"; //TODO } }; struct Order { struct Item { std::string serialnumber, name; Person person; int quantity; }; std::vector<Item> items; }; using Tree = boost::property_tree::ptree; Tree make_tree(Person const& p) { Tree pt; pt.put("<xmlattr>.age", p.age); pt.put("<xmlattr>.passed", p.passed?"Yes":"No"); pt.put_value(p.condition); return pt; } Tree make_tree(Order::Item const& p) { Tree pt; pt.put("SN", p.serialnumber); pt.put("NAME", p.name); pt.put_child("Person", make_tree(p.person)); pt.put("QTY", p.quantity); return pt; } Tree make_tree(Order const& p) { Tree pt; Tree& order = pt.put_child("ORDER", {}); for (auto& item : p.items) order.add_child("ITEM", make_tree(item)); return pt; } #include <iostream> /* * <ORDER> * <ITEM> * <SN>132487A-J</SN> * <NAME>crank casing</NAME> * <Person age="12" passed="Yes">Alive</Person> * <QTY>1</QTY> * </ITEM> * </ORDER> * */ int main() { Order const order { { Order::Item { "132487A-J", "crank casing", Person { 12, true, Person::Alive }, 1 }, } }; using namespace boost::property_tree; auto settings = xml_parser::xml_writer_make_settings<std::string>(' ', 4, "utf-8"); write_xml(std::cout, make_tree(order), settings); }
打印
<?xml version="1.0" encoding="utf-8"?> <ORDER> <ITEM> <SN>132487A-J</SN> <NAME>crank casing</NAME> <Person age="12" passed="Yes">Alive</Person> <QTY>1</QTY> </ITEM> </ORDER>
这里使用Pugi XML。我真的希望这能更方便用户使用。
注释我已经在这里添加了一个非喷子答案,因为我发现时间使用TinyXML
#include <pugixml.hpp>
#include <vector>
#include <iostream>
#include <sstream>
struct Person {
int age;
bool passed;
enum Condition { Alive, Dead } condition;
friend std::ostream& operator<<(std::ostream& os, Condition c) {
switch (c) {
case Alive : return os << "Alive";
case Dead : return os << "Dead";
}
throw "failure"; //TODO
}
};
struct Order {
struct Item {
std::string serialnumber, name;
Person person;
int quantity;
};
std::vector<Item> items;
};
using Tree = pugi::xml_node;
Tree make_tree(Person const& p, pugi::xml_node parent) {
auto pt = parent.append_child("Person");
pt.append_attribute("age").set_value(p.age);
pt.append_attribute("passed").set_value(p.passed?"Yes":"No");
std::ostringstream oss;
oss << p.condition;
pt.append_child(pugi::node_pcdata).set_value(oss.str().c_str());
return pt;
}
Tree make_tree(Order::Item const& p, pugi::xml_node parent) {
auto pt = parent.append_child("ITEM");
pt.append_child("SN").append_child(pugi::node_pcdata).set_value(p.serialnumber.c_str());
pt.append_child("NAME").append_child(pugi::node_pcdata).set_value(p.name.c_str());
make_tree(p.person, pt).set_name("Person");
pt.append_child("QTY").set_value(std::to_string(p.quantity).c_str());
return pt;
}
Tree make_tree(Order const& p, pugi::xml_node parent) {
auto pt = parent.append_child("ORDER");
for (auto& item : p.items)
make_tree(item, pt);
return pt;
}
#include <iostream>
/*
* <ORDER>
* <ITEM>
* <SN>132487A-J</SN>
* <NAME>crank casing</NAME>
* <Person age="12" passed="Yes">Alive</Person>
* <QTY>1</QTY>
* </ITEM>
* </ORDER>
*
*/
int main() {
Order const order {
{
Order::Item {
"132487A-J", "crank casing",
Person { 12, true, Person::Alive },
1
},
}
};
pugi::xml_document doc;
make_tree(order, doc.append_child("ORDER"))
.print(std::cout);
}
没有Live Demo,因为Coliru没有PugiXML。它打印:
<ORDER>
<ITEM>
<SN>132487A-J</SN>
<NAME>crank casing</NAME>
<Person age="12" passed="Yes">Alive</Person>
<QTY />
</ITEM>
</ORDER>
好的,因为您非常有耐心,而且因为我想第一次尝试TinyXml2,所以下面是:
#include <tinyxml2.h>
#include <vector>
#include <iostream>
#include <sstream>
struct Person {
int age;
bool passed;
enum Condition { Alive, Dead } condition;
friend std::ostream& operator<<(std::ostream& os, Condition c) {
switch (c) {
case Alive : return os << "Alive";
case Dead : return os << "Dead";
}
throw "failure"; //TODO
}
};
struct Order {
struct Item {
std::string serialnumber, name;
Person person;
int quantity;
};
std::vector<Item> items;
};
using Tree = tinyxml2::XMLNode;
using Document = tinyxml2::XMLDocument;
Tree* make_tree(Person const& p, Document& doc) {
auto pt = doc.NewElement("Person");
pt->SetAttribute("age", p.age);
pt->SetAttribute("passed", p.passed?"Yes":"No");
std::ostringstream oss;
oss << p.condition;
pt->SetValue(oss.str().c_str());
return pt;
}
Tree* make_tree(Order::Item const& p, Document& doc) {
auto pt = doc.NewElement("ITEM");
(pt->InsertEndChild(doc.NewElement("SN")))->InsertFirstChild(doc.NewText(p.serialnumber.c_str()));
(pt->InsertEndChild(doc.NewElement("NAME")))->InsertFirstChild(doc.NewText(p.name.c_str()));
pt->InsertEndChild(make_tree(p.person, doc));
(pt->InsertEndChild(doc.NewElement("QTY")))->InsertFirstChild(doc.NewText(std::to_string(p.quantity).c_str()));
return pt;
}
Tree* make_tree(Order const& p, Document& doc) {
auto pt = doc.NewElement("ORDER");
for (auto& item : p.items)
pt->InsertEndChild(make_tree(item, doc));
return pt;
}
#include <iostream>
/*
* <ORDER>
* <ITEM>
* <SN>132487A-J</SN>
* <NAME>crank casing</NAME>
* <Person age="12" passed="Yes">Alive</Person>
* <QTY>1</QTY>
* </ITEM>
* </ORDER>
*
*/
int main() {
Order const order {
{
Order::Item {
"132487A-J", "crank casing",
Person { 12, true, Person::Alive },
1
},
}
};
Document doc;
doc.InsertFirstChild(make_tree(order, doc));
tinyxml2::XMLPrinter printer;
doc.Print(&printer);
std::cout << printer.CStr() << "n";
}
打印
<ORDER>
<ITEM>
<SN>132487A-J</SN>
<NAME>crank casing</NAME>
<Alive age="12" passed="Yes"/>
<QTY>1</QTY>
</ITEM>
</ORDER>
相关文章:
- 继承函数的重载解析
- 基类中的函数名称解析
- 提升精神:解析布尔表达式并简化为规范范式
- 我正在使用嵌套的while循环来解析具有多行的文本文件,但由于某种原因,它只通过第一行,我不知道为什么
- gcc和c++17的过载解析失败
- C++:Application.cpp中抛出了未解析的外部符号(解决方案在问题的末尾,供未来的读者参考)
- 构造函数和转换运算符之间的重载解析
- 如何使用tinyxml2从XML加载父实体和子实体
- 未解析的外部符号_MsiLocateComponentW@12.
- '尝试解析可变参数模板时无法推断出'T的模板参数
- 非类型指针和引用模板参数,以及在编译时如何/为什么解析它们.c++
- C++的解析器在可以区分比较和模板实例化之前会做什么?
- 如何在 cpp 中解析此文件?
- 在C++中使用 gRPC 时未解析的外部符号
- 为什么TinyXML2的XMLDocument::FirstChild()函数在尝试解析这个有效的XML文件时返回NULL?
- 解析 tinyXML2 中的注释
- 为什么 tinyxml2 无法解析流量服务器 xml 文件
- TinyXML2解析器c++奇怪标签
- 如何在c++程序中使用TinyXml2解析xml文件
- 如何使用tinyxml2解析空元素?