Как получить XML-файл, проанализированный с помощью TinyXml2 в программе C ++?

Я впервые использую TinyXml2, чтобы получить файл XML следующим образом:

<ORDER>
<ITEM>
<SN>132487A-J</SN>
<NAME>crank casing</NAME>
<Person age="12" passed="Yes">Alive</Person>
<QTY>1</QTY>
</ITEM>
</ORDER>

Итак, как мне получить этот тип xml, созданный в TinyXml2 в visual studio? Я искал в интернете, но они показали примеры очень длинные и сложные для понимания. Итак, предложите мне простой кусок кода на c ++, используя крошечный xml, который может полностью удовлетворить мою цель.

0

Решение

В категории ответов троллей:

Заметка С тех пор я добавил не-тролль ответ Вот, так как я нашел время для работы с TinyXML

  1. Повысить дерево свойств

    Жить на Колиру

    #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>
    
2

Другие решения

Здесь используется 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);
}

Нет живой демоверсии, поскольку у Coliru нет PugiXML. Это печатает:

<ORDER>
<ITEM>
<SN>132487A-J</SN>
<NAME>crank casing</NAME>
<Person age="12" passed="Yes">Alive</Person>
<QTY />
</ITEM>
</ORDER>
1

Хорошо, потому что вы были очень терпеливы, и потому что я хотел попробовать 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>
0
По вопросам рекламы [email protected]