From 6da5983e944d93c2651aaaa3937cac0501021090 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Tue, 10 Aug 2010 06:01:16 +0000 Subject: [PATCH] add xinclude support for libxml2 based parser - thanks oldtopos - closes #567 --- CHANGELOG | 2 ++ src/libxml2_loader.cpp | 11 ++++++++ src/load_map.cpp | 34 ++++++++++++++++-------- utils/upgrade_map_xml/upgrade_map_xml.py | 1 + 4 files changed, 37 insertions(+), 11 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 38d8a3eb2..a4e572745 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -14,6 +14,8 @@ For a complete change history, see the SVN log. Mapnik Trunk ------------ +- Added xinclude (http://www.w3.org/TR/xinclude/) support to libxml2-based xml parser (oldtopos) (#567) + - Optimized rendering speeds by avoiding locking in the projection code (r2063) - Added support for setting global alignment of polygon pattern fills (#203) diff --git a/src/libxml2_loader.cpp b/src/libxml2_loader.cpp index 00e3d2ac1..dce611040 100644 --- a/src/libxml2_loader.cpp +++ b/src/libxml2_loader.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include @@ -147,8 +148,18 @@ public: throw config_error(os.str()); } + int iXIncludeReturn = xmlXIncludeProcessFlags( doc, options_ ); + + if (iXIncludeReturn < 0) + { + xmlFreeDoc(doc); + throw config_error("XML XInclude error. One or more files failed to load."); + } + + xmlNode * root = xmlDocGetRootElement( doc ); if ( ! root ) { + xmlFreeDoc(doc); throw config_error("XML document is empty."); } diff --git a/src/load_map.cpp b/src/load_map.cpp index 5526200d6..bd0eb6065 100644 --- a/src/load_map.cpp +++ b/src/load_map.cpp @@ -83,6 +83,7 @@ public: void parse_map(Map & map, ptree const & sty); private: + void parse_map_include( Map & map, ptree const & include); void parse_style(Map & map, ptree const & sty); void parse_layer(Map & map, ptree const & lay); void parse_metawriter(Map & map, ptree const & lay); @@ -190,8 +191,8 @@ void map_parser::parse_map( Map & map, ptree const & pt ) map.set_buffer_size(*buffer_size); } -// Check if relative paths should be interpreted as relative to/from XML location -// Default is true, and map_parser::ensure_relative_to_xml will be called to modify path + // Check if relative paths should be interpreted as relative to/from XML location + // Default is true, and map_parser::ensure_relative_to_xml will be called to modify path optional paths_from_xml = get_opt_attr(map_node, "paths_from_xml"); if (paths_from_xml) { @@ -243,15 +244,29 @@ void map_parser::parse_map( Map & map, ptree const & pt ) ex.append_context("(in node Map)"); throw; } - - ptree::const_iterator itr = map_node.begin(); - ptree::const_iterator end = map_node.end(); + + parse_map_include( map, map_node ); + } + catch (const boost::property_tree::ptree_bad_path &) + { + throw config_error("Not a map file. Node 'Map' not found."); + } +} + +void map_parser::parse_map_include( Map & map, ptree const & include ) +{ + ptree::const_iterator itr = include.begin(); + ptree::const_iterator end = include.end(); for (; itr != end; ++itr) { ptree::value_type const& v = *itr; - if (v.first == "Style") + if (v.first == "Include") + { + parse_map_include( map, v.second ); + } + else if (v.first == "Style") { parse_style( map, v.second ); } @@ -307,11 +322,8 @@ void map_parser::parse_map( Map & map, ptree const & pt ) v.first + "'"); } } - } - catch (const boost::property_tree::ptree_bad_path &) - { - throw config_error("Not a map file. Node 'Map' not found."); - } + + map.init_metawriters(); } diff --git a/utils/upgrade_map_xml/upgrade_map_xml.py b/utils/upgrade_map_xml/upgrade_map_xml.py index 448c5c0dc..b142bad15 100755 --- a/utils/upgrade_map_xml/upgrade_map_xml.py +++ b/utils/upgrade_map_xml/upgrade_map_xml.py @@ -45,6 +45,7 @@ if __name__ == "__main__": xml = sys.argv[1] tree = objectify.parse(xml) + tree.xinclude() root = tree.getroot() # rename 'bgcolor' to 'background-color'