1 // ----------------------------------------------------------------------------
2 // Copyright (C) 2002-2006 Marcin Kalicinski
4 // Distributed under the Boost Software License, Version 1.0.
5 // (See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
8 // For more information, see www.boost.org
9 // ----------------------------------------------------------------------------
10 #ifndef BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_READ_TINYXML_HPP_INCLUDED
11 #define BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_READ_TINYXML_HPP_INCLUDED
13 #include <boost/property_tree/ptree.hpp>
14 #include <boost/property_tree/detail/xml_parser_error.hpp>
15 #include <boost/property_tree/detail/xml_parser_flags.hpp>
16 #include <boost/property_tree/detail/xml_parser_utils.hpp>
20 namespace boost
{ namespace property_tree
{ namespace xml_parser
26 void read_xml_node(TiXmlNode
*node
, Ptree
&pt
, int flags
)
29 typedef typename
Ptree::key_type::value_type Ch
;
31 if (TiXmlElement
*elem
= node
->ToElement())
33 Ptree
&tmp
= pt
.push_back(std::make_pair(elem
->Value(), Ptree()))->second
;
34 for (TiXmlAttribute
*attr
= elem
->FirstAttribute(); attr
; attr
= attr
->Next())
35 tmp
.put(xmlattr
<Ch
>() + Ch('.') + attr
->Name(), attr
->Value());
36 for (TiXmlNode
*child
= node
->FirstChild(); child
; child
= child
->NextSibling())
37 read_xml_node(child
, tmp
, flags
);
39 else if (TiXmlText
*text
= node
->ToText())
41 if (flags
& no_concat_text
)
42 pt
.push_back(std::make_pair(xmltext
<Ch
>(), Ptree(text
->Value())));
44 pt
.data() += text
->Value();
46 else if (TiXmlComment
*comment
= node
->ToComment())
48 if (!(flags
& no_comments
))
49 pt
.push_back(std::make_pair(xmlcomment
<Ch
>(), Ptree(comment
->Value())));
54 void read_xml_internal(std::basic_istream
<typename
Ptree::key_type::value_type
> &stream
,
57 const std::string
&filename
)
60 // Create and load document from stream
64 BOOST_PROPERTY_TREE_THROW(xml_parser_error("read error", filename
, 0));
66 BOOST_PROPERTY_TREE_THROW(xml_parser_error(doc
.ErrorDesc(), filename
, doc
.ErrorRow()));
68 // Create ptree from nodes
70 for (TiXmlNode
*child
= doc
.FirstChild(); child
; child
= child
->NextSibling())
71 read_xml_node(child
, local
, flags
);
73 // Swap local and result ptrees
81 void read_xml_node(TiXmlNode
*node
, Ptree
&pt
, int flags
)
84 typedef typename
Ptree::key_type::value_type Ch
;
86 if (TiXmlElement
*elem
= node
->ToElement())
88 Ptree
&tmp
= pt
.push_back(std::make_pair(elem
->Value(), Ptree()))->second
;
89 for (TiXmlAttribute
*attr
= elem
->FirstAttribute(); attr
; attr
= attr
->Next())
90 tmp
.put(xmlattr
<Ch
>() + Ch('.') + attr
->Name(), attr
->Value());
91 for (TiXmlNode
*child
= node
->FirstChild(); child
; child
= child
->NextSibling())
92 read_xml_node(child
, tmp
, flags
);
94 else if (TiXmlText
*text
= node
->ToText())
96 if (flags
& no_concat_text
)
97 pt
.push_back(std::make_pair(xmltext
<Ch
>(), Ptree(text
->Value())));
99 pt
.data() += text
->Value();
101 else if (TiXmlComment
*comment
= node
->ToComment())
103 if (!(flags
& no_comments
))
104 pt
.push_back(std::make_pair(xmlcomment
<Ch
>(), Ptree(comment
->Value())));
108 template<class Ptree
>
109 void read_xml_internal(std::basic_istream
<typename
Ptree::key_type::value_type
> &stream
,
112 const std::string
&filename
)
115 // Load data into vector
116 typedef typename
Ptree::key_type::value_type Ch
;
117 std::vector
<Ch
> data(std::istreambuf_iterator
<Ch
>(stream
.rdbuf()),
118 std::istreambuf_iterator
<Ch
>());
120 BOOST_PROPERTY_TREE_THROW(xml_parser_error("read error", filename
, 0));
121 data
.push_back(Ch('\0'));
123 // Create and load document
125 doc
.Parse(&data
.front());
127 BOOST_PROPERTY_TREE_THROW(xml_parser_error(doc
.ErrorDesc(), filename
, doc
.ErrorRow()));
129 // Create ptree from nodes
131 for (TiXmlNode
*child
= doc
.FirstChild(); child
; child
= child
->NextSibling())
132 read_xml_node(child
, local
, flags
);
134 // Swap local and result ptrees