File indexing completed on 2025-01-18 09:50:17
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_READ_RAPIDXML_HPP_INCLUDED
0011 #define BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_READ_RAPIDXML_HPP_INCLUDED
0012
0013 #include <boost/property_tree/ptree.hpp>
0014 #include <boost/property_tree/detail/xml_parser_error.hpp>
0015 #include <boost/property_tree/detail/xml_parser_flags.hpp>
0016 #include <boost/property_tree/detail/xml_parser_utils.hpp>
0017 #include <boost/property_tree/detail/rapidxml.hpp>
0018 #include <vector>
0019
0020 namespace boost { namespace property_tree { namespace xml_parser
0021 {
0022
0023 template<class Ptree, class Ch>
0024 void read_xml_node(detail::rapidxml::xml_node<Ch> *node,
0025 Ptree &pt, int flags)
0026 {
0027 using namespace detail::rapidxml;
0028 switch (node->type())
0029 {
0030
0031 case node_element:
0032 {
0033
0034 Ptree &pt_node = pt.push_back(std::make_pair(node->name(),
0035 Ptree()))->second;
0036
0037
0038 if (node->first_attribute())
0039 {
0040 Ptree &pt_attr_root = pt_node.push_back(
0041 std::make_pair(xmlattr<typename Ptree::key_type>(), Ptree()))->second;
0042 for (xml_attribute<Ch> *attr = node->first_attribute();
0043 attr; attr = attr->next_attribute())
0044 {
0045 Ptree &pt_attr = pt_attr_root.push_back(
0046 std::make_pair(attr->name(), Ptree()))->second;
0047 pt_attr.data() = typename Ptree::key_type(attr->value(), attr->value_size());
0048 }
0049 }
0050
0051
0052 for (xml_node<Ch> *child = node->first_node();
0053 child; child = child->next_sibling())
0054 read_xml_node(child, pt_node, flags);
0055 }
0056 break;
0057
0058
0059 case node_data:
0060 case node_cdata:
0061 {
0062 if (flags & no_concat_text)
0063 pt.push_back(std::make_pair(xmltext<typename Ptree::key_type>(),
0064 Ptree(node->value())));
0065 else
0066 pt.data() += typename Ptree::key_type(node->value(), node->value_size());
0067 }
0068 break;
0069
0070
0071 case node_comment:
0072 {
0073 if (!(flags & no_comments))
0074 pt.push_back(std::make_pair(xmlcomment<typename Ptree::key_type>(),
0075 Ptree(typename Ptree::key_type(node->value(), node->value_size()))));
0076 }
0077 break;
0078
0079 default:
0080
0081 break;
0082 }
0083 }
0084
0085 template<class Ptree>
0086 void read_xml_internal(std::basic_istream<
0087 typename Ptree::key_type::value_type> &stream,
0088 Ptree &pt,
0089 int flags,
0090 const std::string &filename)
0091 {
0092 typedef typename Ptree::key_type::value_type Ch;
0093 using namespace detail::rapidxml;
0094
0095
0096 stream.unsetf(std::ios::skipws);
0097 std::vector<Ch> v(std::istreambuf_iterator<Ch>(stream.rdbuf()),
0098 std::istreambuf_iterator<Ch>());
0099 if (!stream.good())
0100 BOOST_PROPERTY_TREE_THROW(
0101 xml_parser_error("read error", filename, 0));
0102 v.push_back(0);
0103
0104 try {
0105
0106 const int f_tws = parse_normalize_whitespace
0107 | parse_trim_whitespace;
0108 const int f_c = parse_comment_nodes;
0109
0110 const int f_tws_c = parse_normalize_whitespace
0111 | parse_trim_whitespace
0112 | parse_comment_nodes;
0113 xml_document<Ch> doc;
0114 if (flags & no_comments) {
0115 if (flags & trim_whitespace)
0116 doc.BOOST_NESTED_TEMPLATE parse<f_tws>(&v.front());
0117 else
0118 doc.BOOST_NESTED_TEMPLATE parse<0>(&v.front());
0119 } else {
0120 if (flags & trim_whitespace)
0121 doc.BOOST_NESTED_TEMPLATE parse<f_tws_c>(&v.front());
0122 else
0123 doc.BOOST_NESTED_TEMPLATE parse<f_c>(&v.front());
0124 }
0125
0126
0127 Ptree local;
0128 for (xml_node<Ch> *child = doc.first_node();
0129 child; child = child->next_sibling())
0130 read_xml_node(child, local, flags);
0131
0132
0133 pt.swap(local);
0134 } catch (parse_error &e) {
0135 long line = static_cast<long>(
0136 std::count(&v.front(), e.where<Ch>(), Ch('\n')) + 1);
0137 BOOST_PROPERTY_TREE_THROW(
0138 xml_parser_error(e.what(), filename, line));
0139 }
0140 }
0141
0142 } } }
0143
0144 #endif