if (!scan_line (line, lineno))
status = false;
- };
+ }
return status;
}
+namespace
+{
+ // Recursively go through the 'source' tree
+ // and see if we can find corresponding
+ // entries in the 'destination' tree. If
+ // not, error out (i.e. we have just read
+ // an XML file that has entries that
+ // weren't declared in the ParameterHandler
+ // object); if so, copy the value of these
+ // nodes into the destination object
+ bool
+ read_xml_recursively (const boost::property_tree::ptree &source,
+ const std::string ¤t_path,
+ const char path_separator,
+ boost::property_tree::ptree &destination)
+ {
+ for (boost::property_tree::ptree::const_iterator p = source.begin();
+ p != source.end(); ++p)
+ {
+ // a sub-tree must either be a
+ // parameter node or a subsection
+ if (p->second.get_optional<std::string>("value"))
+ {
+ // make sure we have a
+ // corresponding entry in the
+ // destination object as well
+ const std::string full_path
+ = (current_path == ""
+ ?
+ p->first
+ :
+ current_path + path_separator + p->first);
+ if (destination.get_optional<std::string> (full_path)
+ &&
+ destination.get_optional<std::string> (full_path +
+ path_separator +
+ "value"))
+ {
+ // set the found parameter in
+ // the destination argument
+ destination.put (full_path + path_separator + "value",
+ p->second.get_optional<std::string>("value"));
+
+ // this node might have
+ // sub-nodes in addition to
+ // "value", such as
+ // "default_value",
+ // "documentation", etc. we
+ // might at some point in the
+ // future want to make sure
+ // that if they exist that
+ // they match the ones in the
+ // 'destination' tree
+ }
+ else
+ {
+ std::cerr << "The entry <" << full_path
+ << "> with value <"
+ << p->second.get<std::string>("value")
+ << "> has not been declared.";
+ return false;
+ }
+ }
+ else
+ {
+ // it must be a subsection
+ const bool result
+ = read_xml_recursively (p->second,
+ (current_path == "" ?
+ p->first :
+ current_path + path_separator + p->first),
+ path_separator,
+ destination);
+
+ // see if the recursive read
+ // succeeded. if yes, continue,
+ // otherwise exit now
+ if (result == false)
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
+
+
+
+bool ParameterHandler::read_input_from_xml (std::istream &in)
+{
+ // read the XML tree assuming that (as we
+ // do in print_parameters(XML) it has only
+ // a single top-level node called
+ // "ParameterHandler"
+ boost::property_tree::ptree single_node_tree;
+ try
+ {
+ read_xml (in, single_node_tree);
+ }
+ catch (...)
+ {
+ std::cerr << "This input stream appears not to be valid XML"
+ << std::endl;
+ return false;
+ }
+
+ // make sure there is a top-level element
+ // called "ParameterHandler"
+ if (!single_node_tree.get_optional<std::string>("ParameterHandler"))
+ {
+ std::cerr << "There is no top-level XML element called \"ParameterHandler\"."
+ << std::endl;
+ return false;
+ }
+
+ // ensure that there is only a single
+ // top-level element
+ if (std::distance (single_node_tree.begin(), single_node_tree.end()) != 1)
+ {
+ std::cerr << "The top-level XML element \"ParameterHandler\" is "
+ << "not the only one."
+ << std::endl;
+ std::cerr << "(There are "
+ << std::distance (single_node_tree.begin(),
+ single_node_tree.end())
+ << " top-level elements.)"
+ << std::endl;
+ return false;
+ }
+
+ // read the child elements recursively
+ const boost::property_tree::ptree
+ &my_entries = single_node_tree.get_child("ParameterHandler");
+
+ return read_xml_recursively (my_entries, "", path_separator, *entries);
+}
+
+
+
void ParameterHandler::clear ()
{
entries.reset (new boost::property_tree::ptree());
--- /dev/null
+//---------------------------- parameter_handler_read_xml.cc ---------------------------
+// $Id$
+// Version: $Name$
+//
+// Copyright (C) 2002, 2003, 2004, 2005, 2010 by the deal.II authors
+//
+// This file is subject to QPL and may not be distributed
+// without copyright and license information. Please refer
+// to the file deal.II/doc/license.html for the text and
+// further information on this license.
+//
+//---------------------------- parameter_handler_read_xml.cc ---------------------------
+
+
+// check ParameterHandler::print_parameters (..., XML). have a few
+// names that contain all sorts of weird (for XML) characters
+
+#include "../tests.h"
+#include <base/logstream.h>
+#include <base/parameter_handler.h>
+#include <fstream>
+
+
+int main ()
+{
+ std::ofstream logfile("parameter_handler_read_xml/output");
+ deallog.attach(logfile);
+ deallog.depth_console(0);
+ deallog.threshold_double(1.e-10);
+
+ ParameterHandler prm;
+ prm.declare_entry ("int1",
+ "1",
+ Patterns::Integer(),
+ "doc 1");
+ prm.declare_entry ("int2",
+ "2",
+ Patterns::Integer(),
+ "doc 2");
+ prm.enter_subsection ("ss1");
+ {
+ prm.declare_entry ("double 1",
+ "1.234",
+ Patterns::Double(),
+ "doc 3");
+
+ prm.enter_subsection ("ss2");
+ {
+ prm.declare_entry ("double 2",
+ "4.321",
+ Patterns::Double(),
+ "doc 4");
+ }
+ prm.leave_subsection ();
+ }
+ prm.leave_subsection ();
+
+ // things with strange characters
+ prm.enter_subsection ("Testing%testing");
+ {
+ prm.declare_entry ("string&list",
+ "< & > ; /",
+ Patterns::Anything(),
+ "docs 1");
+ prm.declare_entry ("int*int",
+ "2",
+ Patterns::Integer());
+ prm.declare_entry ("double+double",
+ "6.1415926",
+ Patterns::Double(),
+ "docs 3");
+ }
+ prm.leave_subsection ();
+
+ // read from XML
+ std::ifstream in ("parameter_handler_read_xml/prm");
+ bool result = prm.read_input_from_xml (in);
+ Assert (result == true, ExcInternalError());
+
+ // write it out again
+ prm.print_parameters (deallog.get_file_stream(), ParameterHandler::XML);
+ logfile << std::endl;
+
+ return 0;
+}