1 // ----------------------------------------------------------------------------
2 // Copyright (C) 2006-2007 Alexey Baskakov
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 // ----------------------------------------------------------------------------
11 // PugiXML-based parser. To enable it define
12 // BOOST_PROPERTY_TREE_XML_PARSER_PUGIXML before including xml_parser.hpp file.
14 // PugiXML library has to be obtained separately.
15 // Check it out at http://code.google.com/p/pugixml/
17 // This module is derived from an example shipped as part of
18 // the PugiXML documentation. This example contains the following notice:
19 // Copyright (C) 2006, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)
21 #ifndef BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_READ_PUGIXML_HPP_INCLUDED
22 #define BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_READ_PUGIXML_HPP_INCLUDED
24 #include <boost/property_tree/ptree.hpp>
25 #include <boost/property_tree/detail/xml_parser_error.hpp>
26 #include <boost/property_tree/detail/xml_parser_flags.hpp>
27 #include <boost/property_tree/detail/xml_parser_utils.hpp>
29 #include <pugixml.hpp>
31 namespace boost
{ namespace property_tree
{ namespace xml_parser
35 void read_xml_node( pugi::xml_node node
, Ptree
&pt
, int flags
)
37 typedef typename
Ptree::key_type::value_type Ch
;
39 switch ( node
.type() )
41 case pugi::node_element
:
43 Ptree
&tmp
= pt
.push_back(std::make_pair( node
.name(), Ptree()))->second
;
44 for ( pugi::xml_attribute attr
= node
.first_attribute(); attr
; attr
= attr
.next_attribute() )
45 tmp
.put( xmlattr
<Ch
>() + "." + attr
.name(), attr
.value());
46 for ( pugi::xml_node child
= node
.first_child(); child
; child
= child
.next_sibling())
47 read_xml_node(child
, tmp
, flags
);
50 case pugi::node_pcdata
:
52 if (flags
& no_concat_text
)
53 pt
.push_back(std::make_pair(xmltext
<Ch
>(), Ptree( node
.value() )));
55 pt
.data() += node
.value();
58 case pugi::node_comment
:
60 if (!(flags
& no_comments
))
61 pt
.push_back(std::make_pair(xmlcomment
<Ch
>(), Ptree( node
.value() )));
71 void read_xml_internal(std::basic_istream
<typename
Ptree::key_type::value_type
> &stream
,
74 const std::string
&filename
)
76 typedef typename
Ptree::key_type::value_type Ch
;
78 // Create and load document from stream
79 stream
.unsetf(std::ios::skipws
);
82 throw xml_parser_error("read error", filename
, 0);
85 std::copy(std::istream_iterator
<Ch
>(stream
), std::istream_iterator
<Ch
>(), std::back_inserter(buf
));
86 buf
.push_back(0); // zero-terminate
88 unsigned int pugi_flags
= pugi::parse_w3c
;
89 if ( flags
& no_comments
)
90 pugi_flags
= pugi_flags
& ~pugi::parse_comments
;
92 pugi::xml_parser
parser(&buf
[0], pugi_flags
);
93 pugi::xml_node doc
= parser
.document();
95 // Create ptree from nodes
97 for ( pugi::xml_node child
= doc
.first_child(); child
; child
= child
.next_sibling())
98 read_xml_node( child
, local
, flags
);
100 // Swap local and result ptrees