CYCLUS
infile_converters.cc
Go to the documentation of this file.
1 #include <sstream>
2 
3 #include <boost/shared_ptr.hpp>
4 #include <libxml++/libxml++.h>
5 
6 #include "error.h"
7 #include "infile_converters.h"
8 #include "infile_tree.h"
9 #include "pyne.h"
10 
11 namespace cyclus {
12 namespace toolkit {
13 
14 void AddJsonToXml(Json::Value& node, std::stringstream& ss,
15  std::string parent_name, std::string indent) {
16  using std::string;
17  using Json::Value;
18  if (node.isObject()) {
19  bool indent_child;
20  string name;
21  string newindent = indent + " ";
22  Value::Members members = node.getMemberNames();
23  for (int n = 0; n < members.size(); ++n) {
24  name = members[n];
25  if (node[name].isNull()) {
26  ss << indent << "<" << name << "/>\n";
27  continue;
28  }
29  indent_child = node[name].isObject();
30  if (!indent_child && node[name].isArray())
31  indent_child = node[name][0].isObject() || node[name][0].isArray();
32  ss << indent << "<" << name << ">";
33  if (indent_child)
34  ss << "\n";
35  AddJsonToXml(node[name], ss, name, newindent);
36  if (indent_child)
37  ss << indent;
38  ss << "</" << name << ">\n";
39  }
40  } else if (node.isArray()) {
41  bool indent_child;
42  std::string newindent = indent;
43  indent = indent.substr(0, indent.size() - 2);
44  int nchildren = node.size();
45  for (int n = 0; n < nchildren; ++n) {
46  if (node[n].isNull()) {
47  ss << indent << "<" << parent_name << "/>\n";
48  continue;
49  }
50  indent_child = node[n].isObject() || node[n].isArray();
51  if (n > 0) {
52  ss << indent << "<" << parent_name << ">";
53  if (indent_child)
54  ss << "\n";
55  }
56  AddJsonToXml(node[n], ss, parent_name, newindent);
57  if (n < nchildren - 1) {
58  if (indent_child)
59  ss << indent;
60  ss << "</" << parent_name << ">\n";
61  }
62  }
63  } else if (node.isString()) {
64  ss << node.asString();
65  } else if (node.isInt()) {
66  ss << node.asInt64();
67  } else if (node.isUInt()) {
68  ss << node.asUInt64();
69  } else if (node.isDouble()) {
70  ss << node.asDouble();
71  } else if (node.isBool()) {
72  ss << node.asBool();
73  } else {
74  // plain old data
75  ss << node.asString();
76  }
77 }
78 
79 // Converts a JSON string into an equivalent XML string
80 std::string JsonToXml(std::string s) {
81  using std::string;
82  using std::stringstream;
83  using Json::Value;
84 
85  stringstream x;
86 
87  // parse the JSON string
88  Value root;
89  Json::Reader reader;
90  bool parsed = reader.parse(s, root, false);
91  if (!parsed) {
92  string msg = "Failed to parse JSON file into XML:\n" + \
93  reader.getFormattedErrorMessages();
94  throw ValidationError(msg);
95  }
96 
97  // convert to XML
98  AddJsonToXml(root, x, "", "");
99  return x.str();
100 }
101 
102 // inserts a value, or appends to an array
103 void JsonInsertOrAppend(Json::Value& node, std::string key, Json::Value& val) {
104  using std::string;
105  using Json::Value;
106  if (node.isMember(key)) {
107  if (node[key].isArray()) {
108  node[key].append(val);
109  } else {
110  Value keynode = node[key];
111  keynode = Value(Json::arrayValue);
112  keynode.append(node[key]);
113  keynode.append(val);
114  node[key] = keynode;
115  }
116  } else {
117  node[key] = val;
118  }
119 }
120 
121 void AddXmlToJson(InfileTree* xnode, Json::Value& jnode,
122  std::string parent_name) {
123  using std::string;
124  using Json::Value;
125  int n = xnode->NElements();
126  for (int i = 0; i < n; ++i) {
127  string name = xnode->GetElementName(i);
128  InfileTree* subxnode = xnode->SubTree("*", i);
129  Value val;
130  if (subxnode->NElements() == 0) {
131  try {
132  val = Value(subxnode->GetString("."));
133  } catch (cyclus::ValueError& e) {
134  val = Value(Json::nullValue);
135  }
136  } else {
137  val = Value(Json::objectValue);
138  AddXmlToJson(subxnode, val, name);
139  }
140  JsonInsertOrAppend(jnode, name, val);
141  }
142 }
143 
144 // Converts an XML string into an equivalent JSON string
145 std::string XmlToJson(std::string s) {
146  using std::string;
147  using std::stringstream;
148  using Json::Value;
149  stringstream ss (s);
150  boost::shared_ptr<XMLParser> parser = boost::shared_ptr<XMLParser>(
151  new XMLParser());
152  parser->Init(ss);
153  InfileTree xroot(*parser);
154  Value jroot(Json::objectValue);
155  string rootname = parser->Document()->get_root_node()->get_name();
156  jroot[rootname] = Value(Json::objectValue);
157  AddXmlToJson(&xroot, jroot[rootname], rootname);
158  Json::CustomWriter writer = Json::CustomWriter("{", "}", "[", "]", ": ",
159  ", ", " ", 80);
160  return writer.write(jroot);
161 }
162 
163 } // namespace toolkit
164 } // namespace cyclus
virtual int NElements()
Definition: infile_tree.cc:34
bool asBool() const
Definition: pyne.cc:15221
bool isBool() const
Definition: pyne.cc:15669
std::string JsonToXml(std::string s)
Converts a JSON string into an equivalent XML string.
void AddJsonToXml(Json::Value &node, std::stringstream &ss, std::string parent_name, std::string indent)
bool isObject() const
Definition: pyne.cc:15719
For values that are too big, too small, etc.
Definition: error.h:41
A class for extracting information from a given XML parser.
Definition: infile_tree.h:22
For validating files received via IO.
Definition: error.h:71
std::string name(int nuc)
Definition: pyne.cc:2940
bool parse(const std::string &document, Value &root, bool collectComments=true)
Read a Value from a JSON document.
Definition: pyne.cc:13250
Represents a JSON value.
Definition: pyne.h:3224
bool isUInt() const
Definition: pyne.cc:15681
virtual std::string GetElementName(int index=0)
investigates the current status and returns a string representing the name of a given index ...
Definition: infile_tree.cc:93
A helper class to hold xml file data and provide automatic validation.
Definition: xml_parser.h:16
bool isDouble() const
Definition: pyne.cc:15695
bool isMember(const char *key) const
Return true if the object has a member named key.
Definition: pyne.cc:15594
bool isArray() const
Definition: pyne.cc:15713
virtual std::string GetString(std::string query, int index=0)
investigates the current status and returns a string representing the content of a query at a given i...
Definition: infile_tree.cc:54
std::string XmlToJson(std::string s)
Converts an XML string into an equivalent JSON string.
object value (collection of name/value pairs).
Definition: pyne.h:3145
bool isInt() const
Definition: pyne.cc:15675
def indent(text, prefix, predicate=None)
double asDouble() const
Definition: pyne.cc:15167
void AddXmlToJson(InfileTree *xnode, Json::Value &jnode, std::string parent_name)
std::string asString() const
Definition: pyne.cc:15006
Writes a Value in JSON format with custom formatting.
Definition: pyne.h:4696
UInt64 asUInt64() const
Definition: pyne.cc:15120
&#39;null&#39; value
Definition: pyne.h:3138
Int64 asInt64() const
Definition: pyne.cc:15094
InfileTree * SubTree(std::string query, int index=0)
populates a child infile based on a query and index
Definition: infile_tree.cc:132
virtual std::string write(const Value &root)
Definition: pyne.cc:16888
taken directly from OsiSolverInterface.cpp on 2/17/14 from https://projects.coin-or.org/Osi/browser/trunk.
Definition: agent.cc:14
Unserialize a JSON document into a Value.
Definition: pyne.h:4246
bool isString() const
Definition: pyne.cc:15707
Members getMemberNames() const
Return a list of the member names.
Definition: pyne.cc:15614
ArrayIndex size() const
Number of values in array or object.
Definition: pyne.cc:15295
void JsonInsertOrAppend(Json::Value &node, std::string key, Json::Value &val)
Value & append(const Value &value)
Append value to array at the end.
Definition: pyne.cc:15536
array value (ordered list)
Definition: pyne.h:3144