47 if(attribute.first.empty())
49 out <<
' ' << attribute.first
69 for(const auto &element : elements)
70 element.output(out, indent+2);
72 do_indent(out, indent);
75 out << '<
' << '/
' << name << '>
' << "\n";
79 void xmlt::escape(const std::string &s, std::ostream &out)
81 for(const auto ch : s)
106 out << "&#" << std::to_string((unsigned char)ch) << ';
';
111 static_cast<unsigned char>(ch) >= 32u,
112 "XML does not support escaping non-printable character " +
113 std::to_string((unsigned char)ch));
121 void xmlt::escape_attribute(const std::string &s, std::ostream &out)
123 for(const auto ch : s)
147 out << "&#
" << std::to_string((unsigned char)ch) << ';';
152 static_cast<unsigned char>(ch) >= 32u,
153 "XML does not support escaping non-printable character
" +
154 std::to_string((unsigned char)ch));
160 bool xmlt::is_printable_xml(const std::string &s)
162 for(const auto ch : s)
164 if(ch < 0x20 && ch != 0x9 && ch != 0xA && ch != 0xD)
171 void xmlt::do_indent(std::ostream &out, unsigned indent)
173 out << std::string(indent, ' ');
176 xmlt::elementst::const_iterator xmlt::find(const std::string &key) const
178 for(elementst::const_iterator it=elements.begin();
184 return elements.end();
187 xmlt::elementst::iterator xmlt::find(const std::string &key)
189 for(elementst::iterator it=elements.begin();
195 return elements.end();
198 void xmlt::set_attribute(
199 const std::string &attribute,
202 set_attribute(attribute, std::to_string(value));
205 void xmlt::set_attribute(
206 const std::string &attribute,
209 set_attribute(attribute, std::to_string(value));
212 void xmlt::set_attribute(
213 const std::string &attribute,
214 unsigned long long value)
216 set_attribute(attribute, std::to_string(value));
219 void xmlt::set_attribute(
220 const std::string &attribute,
221 const std::string &value)
223 if((value[0]=='\"' && value[value.size()-1]=='\"') ||
224 (value[0]=='\'' && value[value.size()-1]=='\''))
226 attributes[attribute]=value.substr(1, value.size()-2);
230 attributes[attribute]=value;
237 std::string xmlt::unescape(const std::string &str)
241 result.reserve(str.size());
243 for(std::string::const_iterator it=str.begin();
252 while(it!=str.end() && *it!=';')
261 else if(tmp[0]=='#' && tmp[1]!='x')
263 char c=unsafe_string2int(tmp.substr(1, tmp.size()-1));
267 throw deserialization_exceptiont("unknown XML
escape code:
" + tmp);
275 bool operator==(const xmlt &a, const xmlt &b)
277 return a.name == b.name && a.data == b.data && a.elements == b.elements &&
278 a.attributes == b.attributes;
280 bool operator!=(const xmlt &a, const xmlt &b)
285 xmlt xml_node(const std::pair<labelt, structured_data_entryt> &entry)
287 const labelt &label = entry.first;
288 const structured_data_entryt &data = entry.second;
289 xmlt output_data{label.kebab_case()};
292 output_data.data = data.leaf_data();
296 const auto &children = data.children();
297 output_data.elements =
298 make_range(children).map(xml_node).collect<std::list<xmlt>>();
303 xmlt to_xml(const structured_datat &data)
305 if(data.data().size() == 0)
307 if(data.data().size() == 1)
309 return xml_node(*data.data().begin());
315 make_range(data.data()).map(xml_node).collect<std::list<xmlt>>();
void output(std::ostream &out, unsigned indent=0) const
static void escape(const std::string &s, std::ostream &out)
escaping for XML elements
static void escape_attribute(const std::string &s, std::ostream &out)
escaping for XML attributes, assuming that double quotes " are used consistently, not single quotes
static void do_indent(std::ostream &out, unsigned indent)
xmlt xml(const irep_idt &property_id, const property_infot &property_info)
#define PRECONDITION(CONDITION)