Code:
//;-*-c++-*-
/*! \file XMLUtils.cpp
\brief
\author Andrew I. James
\date 2004-2007
\version 1.0.0
For full copyright information see the file COPYING in the top level directory.
\license Copyright (C) 2004-2007 Andrew I. James
- ajames at waterqualitymodeling dot com -
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either * version 2 of the License, or (at your
option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
675 Mass Ave, Cambridge, MA 02139, USA.
*/
//-*-*- EH -*-*-//
#include "Misc/XMLUtils.hpp"
namespace wqxml {
using namespace boost::gregorian;
using namespace boost::posix_time;
using namespace boost::local_time;
typedef boost::shared_ptr<ptime> ptime_ptr;
typedef boost::shared_ptr<time_iterator> time_iterator_ptr;
typedef boost::shared_ptr<time_duration> time_duration_ptr;
xmlNodePtr
get_node( xmlNodePtr start, const std::string& name, bool outermost )
{
xmlNodePtr curr_node = NULL;
xmlNodePtr found_node = NULL;
for ( curr_node = start; curr_node; curr_node = curr_node->next ) {
if ( curr_node->type == XML_ELEMENT_NODE && xmlStrEqual(curr_node->name, BAD_CAST name.c_str( )) ) {
found_node = curr_node;
break;
}
found_node = get_node(curr_node->children, name, false);
if ( found_node != NULL ) break;
}
if ( outermost ) XML_THROW_IF_NODE_NOT_FOUND( found_node, name );
return found_node;
}
xmlNodePtr
get_child_node( xmlNodePtr start, const std::string& name, bool throw_if_nil )
{
xmlNodePtr curr_node;
xmlNodePtr found_node = NULL;
// std::cerr << "Name: " << name << " line: " << start->line << std::endl;
try {
for ( curr_node = start->children; curr_node; curr_node = curr_node->next ) {
if ( curr_node->type == XML_ELEMENT_NODE && xmlStrEqual(curr_node->name, BAD_CAST name.c_str()) ) {
found_node = curr_node;
break;
}
}
if ( throw_if_nil ) XML_THROW_IF_NODE_NOT_FOUND( found_node, name );
}
catch ( const std::exception& error ) {
std::cerr << error.what( ) << std::endl;
assert( 0 );
}
return found_node;
}
std::string get_node_name( xmlNodePtr np )
{
XML_THROW_IF_BAD_NODE( np );
std::string n_name((char*)np->name);
std::istringstream iss(n_name);
std::string the_name;
iss >> std::skipws >> the_name;
return the_name;
}
bool property_is_equal_to( xmlNodePtr np, const char* prop_name, const char* prop_val )
{
XML_THROW_IF_BAD_NODE( np );
xmlChar* char_name = xmlGetProp( np, BAD_CAST prop_name );
XML_THROW_IF_ATTRIBUTE_NOT_FOUND( (char*)char_name, prop_name );
bool prop_is_equal( xmlStrEqual( char_name, BAD_CAST prop_val ) );
xmlFree( char_name );
return prop_is_equal;
}
template<typename T>
T get_property( xmlNodePtr np, const char* prop_name, bool throw_if_nil )
{
XML_THROW_IF_BAD_NODE( np );
xmlChar* char_name = xmlGetProp( np, BAD_CAST prop_name );
if ( throw_if_nil ) XML_THROW_IF_ATTRIBUTE_NOT_FOUND( (char*)char_name, prop_name );
std::istringstream iss(( char_name != NULL ) ? (char*)char_name : "");
T the_content;
if ( char_name != NULL ) iss >> std::skipws >> the_content;
xmlFree( char_name );
return the_content;
}
// Make sure this doesn't mung up the specialization with <bool>, below.
template<typename T>
T get_property( xmlNodePtr np, const char* prop_name, const T& default_val, int dummy )
{
XML_THROW_IF_BAD_NODE( np );
xmlChar* char_name = xmlGetProp( np, BAD_CAST prop_name );
T the_content(default_val);
if ( char_name != NULL ) {
std::istringstream iss( (char*)char_name );
iss >> std::skipws >> the_content;
}
xmlFree( char_name );
return the_content;
}
// Force instantiation
template std::string get_property<std::string>( xmlNodePtr np, const char* prop_name,
bool throw_if_nil );
template std::string get_property<std::string>( xmlNodePtr np, const char* prop_name, const std::string& def, int dummy );
template double get_property<double>( xmlNodePtr np, const char* prop_name, bool throw_if_nil );
template int get_property<int>( xmlNodePtr np, const char* prop_name, bool throw_if_nil );
template double get_property<double>( xmlNodePtr np, const char* prop_name, const double& default_val, int dummy );
template<>
bool get_property<bool>( xmlNodePtr np, const char* prop_name, bool throw_if_nil )
{
XML_THROW_IF_BAD_NODE( np );
xmlChar* char_name = xmlGetProp( np, BAD_CAST prop_name );
if ( throw_if_nil ) XML_THROW_IF_ATTRIBUTE_NOT_FOUND( (char*)char_name, prop_name );
std::istringstream iss(( char_name != NULL ) ? (char*)char_name : "");
bool the_content;
iss >> std::skipws >> std::boolalpha >> the_content;
xmlFree( char_name );
return the_content;
}
template<>
bool get_property<bool>( xmlNodePtr np, const char* prop_name, const bool& default_val, int dummy )
{
XML_THROW_IF_BAD_NODE( np );
xmlChar* char_name = xmlGetProp( np, BAD_CAST prop_name );
bool the_content(default_val);
if ( char_name != NULL ) {
std::istringstream iss( (char*)char_name );
iss >> std::skipws >> std::boolalpha >> the_content;
}
xmlFree( char_name );
return the_content;
}
template<>
std::vector<int> get_property<std::vector<int> >( xmlNodePtr np, const char* prop_name, bool throw_if_nil )
{
XML_THROW_IF_BAD_NODE( np );
xmlChar* char_name = xmlGetProp( np, BAD_CAST prop_name );
if ( throw_if_nil ) XML_THROW_IF_ATTRIBUTE_NOT_FOUND( (char*)char_name, prop_name );
std::istringstream iss(( char_name != NULL ) ? (char*)char_name : "");
std::vector<int> the_content;
while ( !iss.eof( ) ) {
int entry(0);
iss >> std::skipws >> entry;
the_content.push_back(entry);
}
xmlFree( char_name );
return the_content;
}
template<>
std::vector<std::string> get_property<std::vector<std::string> >( xmlNodePtr np, const char* prop_name, bool throw_if_nil )
{
XML_THROW_IF_BAD_NODE( np );
xmlChar* char_name = xmlGetProp( np, BAD_CAST prop_name );
if ( throw_if_nil ) XML_THROW_IF_ATTRIBUTE_NOT_FOUND( (char*)char_name, prop_name );
std::istringstream iss(( char_name != NULL ) ? (char*)char_name : "");
std::vector<std::string> the_content;
while ( !iss.eof( ) ) {
std::string entry;
iss >> std::skipws >> entry;
the_content.push_back(entry);
}
xmlFree( char_name );
// for ( int i = 0; i < the_content.size( ); ++i ) std::cout << the_content[i] << std::endl;
return the_content;
}
char get_action_property( xmlNodePtr np, bool throw_if_nil )
{
XML_THROW_IF_BAD_NODE( np );
xmlChar* char_name = xmlGetProp( np, BAD_CAST "action" );
if ( throw_if_nil ) XML_THROW_IF_ATTRIBUTE_NOT_FOUND( (char*)char_name, "action" );
char ret_val = ( xmlStrEqual( char_name, BAD_CAST "mult" ) ) ? '*' : '/';
xmlFree( char_name );
return ret_val;
}
template<typename T>
T get_node_content( xmlNodePtr np, bool throw_if_nil )
{
XML_THROW_IF_BAD_NODE( np );
xmlChar* char_name = xmlNodeGetContent( np );
if ( throw_if_nil ) XML_THROW_IF_CONTENT_NOT_FOUND( (char*)char_name, (char*)np->name );
std::istringstream iss(( char_name != NULL ) ? (char*)char_name : "");
T the_content;
iss >> std::skipws >> the_content;
xmlFree( char_name );
return the_content;
}
// Have to force instantiation
template std::string get_node_content<std::string>( xmlNodePtr np, bool throw_if_nil );
template double get_node_content<double>( xmlNodePtr np, bool throw_if_nil );
template int get_node_content<int>( xmlNodePtr np, bool throw_if_nil );
template<>
bool get_node_content<bool>( xmlNodePtr np, bool throw_if_nil )
{
XML_THROW_IF_BAD_NODE( np );
xmlChar* char_name = xmlNodeGetContent( np );
if ( throw_if_nil ) XML_THROW_IF_CONTENT_NOT_FOUND( (char*)char_name, (char*)np->name );
std::istringstream iss(( char_name != NULL ) ? (char*)char_name : "");
bool the_content;
iss >> std::skipws >> std::boolalpha >> the_content;
xmlFree( char_name );
return the_content;
}
template<>
ptime_ptr get_node_content<ptime_ptr>( xmlNodePtr np, bool throw_if_nil )
{
XML_THROW_IF_BAD_NODE( np );
xmlChar* char_name = xmlNodeGetContent( np );
if ( throw_if_nil ) XML_THROW_IF_CONTENT_NOT_FOUND( (char*)char_name, (char*)np->name );
std::stringstream ss(( char_name != NULL ) ? (char*)char_name : "");
ptime_ptr pt( new ptime(not_a_date_time) );
ss >> *pt;
xmlFree( char_name );
return pt;
}
// double get_node_content_as_double( xmlNodePtr np, bool throw_if_nil )
// {
// XML_THROW_IF_BAD_NODE( np );
// xmlChar* char_name = xmlNodeGetContent( np );
// if ( throw_if_nil ) XML_THROW_IF_CONTENT_NOT_FOUND( (char*)char_name, (char*)np->name );
// // std::string
// double val = ( char_name != NULL ) ? atof((char*)char_name) : 0.0 ;
// return val;
// }
std::string get_node_content_with_whitespace( xmlNodePtr np, bool throw_if_nil )
{
XML_THROW_IF_BAD_NODE( np );
xmlChar* char_name = xmlNodeGetContent( np );
if ( throw_if_nil ) XML_THROW_IF_CONTENT_NOT_FOUND( (char*)char_name, (char*)np->name );
std::istringstream iss(( char_name != NULL ) ? (char*)char_name : "");
xmlFree( char_name );
return iss.str( );
}
std::string xml_xpath_get_string( xmlNodePtr np, const std::string& name, bool throw_if_nil )
{
if ( throw_if_nil ) XML_THROW_IF_BAD_NODE( np );
std::string the_name = (char*) xmlNodeGetContent( np );
return the_name;
}
bool xml_xpath_get_bool( xmlNodePtr np, const std::string& name, bool throw_if_nil )
{
if ( throw_if_nil ) XML_THROW_IF_BAD_NODE( np );
xmlChar* cp = xmlNodeGetContent( np );
// perhaps not use a string for this...
std::string the_bool = ( cp != NULL ) ? (char*)cp : "" ;
xmlFree( cp );
return ( the_bool == "true" || the_bool == "True" || the_bool == "yes"
|| the_bool == "Yes" || the_bool == "1" );
}
double xml_xpath_get_double( xmlNodePtr np, const std::string& name, bool throw_if_nil )
{
if ( throw_if_nil ) XML_THROW_IF_BAD_NODE( np );
xmlChar* cp = xmlNodeGetContent( np );
double ret_val = ( cp != NULL ) ? atof((char*)cp) : 0.0;
xmlFree( cp );
return ret_val;
}
};
I've had no dice on codeguru so here's hoping you guys & gals can give me some hope...