0

I am using TinyXml2 for the first time to get a xml file as follows:

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

So, how will i get this type of xml genrated from TinyXml2 in visual studio. I have searched on internet but they have shown examples realy lengthy and complex to understand. So, kindly suggest me simple piece of code in c++ using tiny xml which can full my purpose.

1

3 Answers 3

2

In the troll answer category:

Note I've since added a non-troll answer here, since I found the time to work with TinyXML

  1. Boost Property Tree

    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);
    }
    

    Prints

    <?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>
    
Sign up to request clarification or add additional context in comments.

Comments

1

Here's using Pugi XML. I was really hoping this would be more user-friendly.

Note I've since added a non-troll answer here, since I found the time to work with 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);
}

No Live Demo, since Coliru doesn't have PugiXML. It prints:

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

Comments

0

Ok, because you were very patient, and because I wanted to try out TinyXml2 for the first time, here goes:

#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";
}

Prints

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.