Xml in Cilk
#include <cilk/cilk.h>
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <pugixml.hpp>
// Plant will be mapped to XML. We use pugixml library for XML operations.
struct Plant {
int id;
std::string name;
std::vector<std::string> origin;
std::string toString() const {
std::stringstream ss;
ss << "Plant id=" << id << ", name=" << name << ", origin=[";
for (const auto& o : origin) {
ss << o << " ";
}
ss << "]";
return ss.str();
}
};
int main() {
Plant coffee = {27, "Coffee", {"Ethiopia", "Brazil"}};
// Emit XML representing our plant
pugi::xml_document doc;
pugi::xml_node plant = doc.append_child("plant");
plant.append_attribute("id") = coffee.id;
plant.append_child("name").text().set(coffee.name.c_str());
for (const auto& o : coffee.origin) {
plant.append_child("origin").text().set(o.c_str());
}
std::stringstream ss;
doc.save(ss, " ");
std::cout << ss.str() << std::endl;
// Add a generic XML header to the output
std::cout << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" << ss.str() << std::endl;
// Parse XML back into a Plant struct
pugi::xml_document doc2;
doc2.load_string(ss.str().c_str());
Plant p;
p.id = doc2.child("plant").attribute("id").as_int();
p.name = doc2.child("plant").child("name").text().get();
for (pugi::xml_node origin = doc2.child("plant").child("origin"); origin; origin = origin.next_sibling("origin")) {
p.origin.push_back(origin.text().get());
}
std::cout << p.toString() << std::endl;
// Create a nested XML structure
Plant tomato = {81, "Tomato", {"Mexico", "California"}};
pugi::xml_document nesting_doc;
pugi::xml_node nesting = nesting_doc.append_child("nesting");
pugi::xml_node parent = nesting.append_child("parent");
pugi::xml_node child = parent.append_child("child");
cilk_spawn [&] {
pugi::xml_node coffee_node = child.append_child("plant");
coffee_node.append_attribute("id") = coffee.id;
coffee_node.append_child("name").text().set(coffee.name.c_str());
for (const auto& o : coffee.origin) {
coffee_node.append_child("origin").text().set(o.c_str());
}
}();
cilk_spawn [&] {
pugi::xml_node tomato_node = child.append_child("plant");
tomato_node.append_attribute("id") = tomato.id;
tomato_node.append_child("name").text().set(tomato.name.c_str());
for (const auto& o : tomato.origin) {
tomato_node.append_child("origin").text().set(o.c_str());
}
}();
cilk_sync;
std::stringstream nesting_ss;
nesting_doc.save(nesting_ss, " ");
std::cout << nesting_ss.str() << std::endl;
return 0;
}
This Cilk code demonstrates XML handling using the pugixml library, which is a lightweight XML processing library for C++. The code structure and functionality are similar to the original example, with some adaptations to fit Cilk and C++ paradigms.
Key points:
We use
struct
instead of Go’stype
to define thePlant
structure.XML operations are performed using the pugixml library instead of Go’s
encoding/xml
package.The
MarshalIndent
andUnmarshal
operations are replaced with pugixml’s document creation and parsing methods.Cilk’s parallel constructs (
cilk_spawn
andcilk_sync
) are used to demonstrate concurrent XML node creation for the nested structure.Error handling is simplified for brevity. In a production environment, you would want to add proper error checking.
The
toString()
method is used instead of Go’sString()
method for string representation of thePlant
struct.
To run this program, you would need to compile it with a Cilk-compatible compiler and link it with the pugixml library. The output would be similar to the Go version, showing the XML representations of the Plant
structures and the nested XML structure.