From: Arjen Baart Date: Wed, 5 Aug 2020 06:03:15 +0000 (+0200) Subject: XML: Access to attributes X-Git-Url: http://www.andromeda.nl/gitweb/?a=commitdiff_plain;h=284ca9d72a38e5fa24c8032fa9347cd2b6bffd93;p=libacl.git XML: Access to attributes --- diff --git a/TODO b/TODO index 0909e93..8d34e6e 100644 --- a/TODO +++ b/TODO @@ -14,5 +14,6 @@ Things to do: - UTC: Convert to and from struct tm -- xml: Add access to attributes - xml: Xinclude processing + +- configuraion: Handle environment variables to override parameters diff --git a/doc/configuration.xml b/doc/configuration.xml new file mode 100644 index 0000000..f229ddd --- /dev/null +++ b/doc/configuration.xml @@ -0,0 +1,56 @@ + +configuration - Class for configuration parameters + +
+#include <configuration.h>
+
+configuration config;
+
+ + +Handle configurational parameters for the application. +Many applications need some permanently stored configurational +data. The information is usually stored in two places: A system- +wide configuration file and a configuration file per user. +The content of the configuration file is in XML format. +The configuration base class takes care of finding the configuration +files, e.g. in /etc/app.conf or in /usr/local/etc/app.conf, along +with the configuration file in the user's home directory. +The config files are parsed with the gnome XML parser and a +framework is provided to find configurational items. + + + +
+Class configuration + +Hold the configuration data for an application. +Both the system-wide configuration and a user-specific configuration are stores in a configuration object. + + + +The default constructor creates an empty configuration. + + +Find the config files and parse the XML. +Both the filename and the root element of the XML files must match the name. +Two configuarions are read. The system and the user config. +First system config in /etc and if it does not exist, in /usr/local/etc. +The user config is read from the current directory. +If that does not exist, try the home directory. + + + + + + +Return the value of a config parameter. +The parameter is obtained from the system-wide config. +If the parameter is also defined in the user config, this will override the value in the system config. + + + +
+ + +
diff --git a/doc/manual.xml b/doc/manual.xml index 629da30..b124508 100644 --- a/doc/manual.xml +++ b/doc/manual.xml @@ -19,5 +19,7 @@ xmlns:xi="http://www.w3.org/2001/XInclude"/> + diff --git a/doc/utc.xml b/doc/utc.xml index 11b102d..bf242ea 100644 --- a/doc/utc.xml +++ b/doc/utc.xml @@ -20,6 +20,9 @@ The default constructor creates a default of its parts. Parse the date and time from String s. + +Convert the UNIX time_t, defined as the number of seconds since the Epoch to a UTC object. + @@ -37,6 +40,9 @@ Parse the date and time from String s. String() + +time_t() - Convert to the UNIX time_t. + @@ -66,7 +72,9 @@ String() - + +Calculate the number of seconds from t2 to t1; + diff --git a/doc/xml.xml b/doc/xml.xml index 09b1da4..5cc18ed 100644 --- a/doc/xml.xml +++ b/doc/xml.xml @@ -105,6 +105,13 @@ of the XML document. Find the child elements with the specified tagname. + +Find the value of an attribute. +Return an empty string is the attribute does not exist. + + +Find all attributes of the element in a map. + diff --git a/src/configuration.cpp b/src/configuration.cpp index cbd2745..59408a7 100644 --- a/src/configuration.cpp +++ b/src/configuration.cpp @@ -5,7 +5,7 @@ ** MODULE INFORMATION * *********************** ** FILE NAME : configuration.cpp -** SYSTEM NAME : AXE - Andromeda X-windows Encapsulation +** SYSTEM NAME : ACL - Andromeda Class Library ** VERSION NUMBER : $Revision: 1.6 $ ** ** DESCRIPTION : Implementation of configuration class @@ -22,34 +22,6 @@ ** MODIFICATIONS : **************************************************************************/ -/***************************** - $Log: configuration.cpp,v $ - Revision 1.6 2007-05-04 14:01:22 arjen - Added new arguments to configuration::find_parameter() to allow for a list of - sections and a list of parameters in sections. - The new arguments are section index and parameter index (default = 0). - - Revision 1.5 2003/03/29 07:19:37 arjen - Bugfix: Do not read the config file in the home - directory if the HOME environment variable doesn't exist - - Revision 1.4 2002/11/23 12:48:18 arjen - Check if a configuration file exists before feeding it to the XML parser. - - Revision 1.3 2002/11/02 14:35:15 arjen - Uses the XML2 library - BugFix: segfault when finding a parameters that is not in the user-sepcific - config tree. - - Revision 1.2 2002/09/28 06:48:46 arjen - Bugfix: In configuration::find_parameter(), check if the parameter node exists - before retrieving its contents. - - Revision 1.1 2002/07/25 08:01:26 arjen - First checkin, AXE release 0.2 - -*****************************/ - #include #include #include "configuration.h" diff --git a/src/configuration.h b/src/configuration.h index c894a43..4af5ec3 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -4,14 +4,14 @@ ** MODULE INFORMATION * *********************** ** FILE NAME : configuration.h -** SYSTEM NAME : AXE - Andromeda X-windows Encapsulation +** SYSTEM NAME : ACL - Andromeda class Library ** VERSION NUMBER : $Revision: 1.4 $ ** ** DESCRIPTION : Definition of configuration class ** ** EXPORTED OBJECTS : class configuration ** LOCAL OBJECTS : -** MODULES USED : String +** MODULES USED : String, XML *************************************************************************** ** ADMINISTRATIVE INFORMATION * ******************************** @@ -21,27 +21,6 @@ ** MODIFICATIONS : **************************************************************************/ -/***************************** - $Log: configuration.h,v $ - Revision 1.4 2007-05-04 14:01:22 arjen - Added new arguments to configuration::find_parameter() to allow for a list of - sections and a list of parameters in sections. - The new arguments are section index and parameter index (default = 0). - - Revision 1.3 2002/11/02 14:35:15 arjen - Uses the XML2 library - BugFix: segfault when finding a parameters that is not in the user-sepcific - config tree. - - Revision 1.2 2002/09/02 06:18:20 arjen - Fixed some date and time conversion functions - - Revision 1.1 2002/07/25 08:01:26 arjen - First checkin, AXE release 0.2 - -*****************************/ - -/* static const char *RCSID = "$Id: configuration.h,v 1.4 2007-05-04 14:01:22 arjen Exp $"; */ #ifndef CONFIGURATION_H #define CONFIGURATION_H diff --git a/src/superstring.cpp b/src/superstring.cpp index c2d6696..694cb93 100644 --- a/src/superstring.cpp +++ b/src/superstring.cpp @@ -70,7 +70,7 @@ String SuperString::join(const String &separator) if (_ss.size() != 0) { joined = _ss[0]; - for (int i = 1; i < _ss.size(); i++) + for (unsigned i = 1; i < _ss.size(); i++) { joined += separator + _ss[i]; } diff --git a/src/xml.cpp b/src/xml.cpp index 3e9267a..30b1109 100644 --- a/src/xml.cpp +++ b/src/xml.cpp @@ -1,10 +1,13 @@ #include "xml.h" +/* + * class xml + */ + void xml::ParseFile(const char * filename) { ctxt = xmlNewParserCtxt(); - //document = xmlParseFile(filename); document = xmlCtxtReadFile(ctxt, filename, NULL, XML_PARSE_NOWARNING|XML_PARSE_NOERROR); } @@ -22,6 +25,10 @@ String xml::RootElementName(void) return root_name; } +/* + * class xml_node + */ + xml_node xml::RootNode(void) { xmlNodePtr root; @@ -31,11 +38,6 @@ xml_node xml::RootNode(void) return xml_node(root); } -//xml_node::xml_node(xml doc) -//{ -// *this = doc.RootNode(); -//} - // Find the nth child element by name (non-recursive) xml_node xml_node::operator[](int i) { @@ -72,6 +74,10 @@ xml_node xml_node::FindChildElement(String name, int nth) } +/* + * class xml_element + */ + std::vector xml_element::operator[](String tagname) { std::vector elements_found; @@ -89,3 +95,44 @@ std::vector xml_element::operator[](String tagname) return elements_found; } + +String xml_element::attribute(String name) +{ + String value; + + struct _xmlAttr *prop_list; + prop_list = n->properties; + + while (prop_list != NULL) + { + if (name == (const char *)prop_list->name) + { + value = (const char *)prop_list->children->content; + } + prop_list = prop_list->next; + } + + return value; +} + +std::map xml_element::attributes(void) +{ + std::map attrs; + struct _xmlAttr *prop_list; + + prop_list = n->properties; + + while (prop_list != NULL) + { + String name, value; + + name = String((const char *)prop_list->name); + value = String((const char *)prop_list->children->content); + + attrs[name] = value; + + prop_list = prop_list->next; + } + + return attrs; +} diff --git a/src/xml.h b/src/xml.h index 4579a17..3b98aeb 100644 --- a/src/xml.h +++ b/src/xml.h @@ -1,5 +1,6 @@ #include // usually in /usr/include/libxml2, see xml2-config #include +#include #include "String.h" @@ -131,5 +132,8 @@ public: std::vector operator[](String tagname); + String attribute(String name); + std::map attributes(void); + }; diff --git a/test/Makefile.am b/test/Makefile.am index c5ce407..1576eae 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -9,7 +9,7 @@ check_PROGRAMS = string_assign string_basics string_compare string_cat string_co hour_assign hour_parse hour_compare hour_arithmetic hour_check_now \ utc_assign utc_parse utc_compare utc_arithmetic utc_convert \ integer_assign integer_factorial integer_fibonacci integer_pow64 integer_modulo \ - xml_file xml_find xml_node xml_elem \ + xml_file xml_find xml_node xml_elem xml_elem_attr \ configuration_read configuration_find string_assign_SOURCES = string_assign.cpp @@ -61,6 +61,7 @@ xml_file_SOURCES = xml_file.cpp xml_find_SOURCES = xml_find.cpp xml_node_SOURCES = xml_node.cpp xml_elem_SOURCES = xml_elem.cpp +xml_elem_attr_SOURCES = xml_elem_attr.cpp configuration_read_SOURCES = configuration_read.cpp configuration_find_SOURCES = configuration_find.cpp diff --git a/test/xml_elem_attr.cpp b/test/xml_elem_attr.cpp new file mode 100644 index 0000000..0837c35 --- /dev/null +++ b/test/xml_elem_attr.cpp @@ -0,0 +1,44 @@ +/******************************************************* + * Unit test for the xml_element class + * + * test xml attributes access + ****************************************************** + * + */ + +#include "xml.h" +#include + +int main() +{ + xml doc; + + const char xml_file[] = "xml_test01.xml"; + + std::cout << "Reading XML file " << xml_file << "\n"; + + doc.ParseFile("xml_test01.xml"); + + xml_element root_node(doc); + + std::cout << "Root element is " << root_node.name() << "\n"; + std::cout << "Root node type is " << root_node.type() << "\n"; + assert(root_node.name() == "doc"); + + //std::vector book; + xml_element book; + std::map book_attrs; + + book = root_node["book"][0]; + book_attrs = book.attributes(); + + std::cout << book_attrs.size() << " attributes in element book.\n"; + std::cout << "Attribute id = " << book_attrs["id"] << "\n"; + assert(book_attrs["id"] == "toplevel"); + + std::cout << "Attribute layout = " << book.attribute("layout") << "\n"; + assert(book.attribute("layout") == "A4"); + + return 0; +} + diff --git a/test/xml_elem_attr.exp b/test/xml_elem_attr.exp new file mode 100644 index 0000000..f0642b1 --- /dev/null +++ b/test/xml_elem_attr.exp @@ -0,0 +1,7 @@ +Reading XML file xml_test01.xml +Root element is doc +Root node type is 1 +3 attributes in element book. +Attribute id = toplevel +Attribute layout = A4 +PASS xml_elem_attr (exit status: 0) diff --git a/test/xml_test01.xml b/test/xml_test01.xml index dcfd8d3..e7dd907 100644 --- a/test/xml_test01.xml +++ b/test/xml_test01.xml @@ -1,12 +1,12 @@ - + Andromeda Class Library - + Chapter 1