From c7be629d44d4e2be6c8116796714e0042a977885 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Tue, 28 Apr 2009 11:12:58 +0200 Subject: Added generic XML -> Python parser The xmlpythonizer module will convert any XML data (xmlNode or xmlDoc) and format it as a Python object. The formatting is defined in it's own XML file. Basic format: The keytype and key attributes defines the key in the Python Dict. The root element will always be a Python Dict structure. The valid key types are: * constant Uses the value in {key} as the key value * string, integer, float Uses a string value from the data XML to be converted to Python. The value set in the key attribute defines an XPath value which points to the data to be used as a Python dict key. Since Python only supports C strings in the C interface for Python dict keys, integer and float will be treated as strings. The valuetype and value attributes are similar to the keys, but with some more features. Valid valuetypes are: * constant The value given in the value attribute will be used in the value in the Python result. * string, integer, float The value given in the value attribute defines the XPath to the data XML, of where to retrieve the value for the given key. The valuetype defines if the data should be understood as a string, integer or float in the Python result. * list:string, list:integer, list:float This does the same as the string, integer or float type, with a tweak. The data will be put into a list. If the XPath given returns multiple nodes, all of them will be added to this list. * dict The dict valuetype is more special. It should not contain any value attribute. On the other hand, it should contain a sub-level of tags. In this way, you can build up a multi dimensional Python dict. Example: ** pythonmap.xml ** ** exampledata.xml ** String value #1 More test data Value1 in list Value2 in list Value3 in list ** C code snippet ** void xmlpythonizer() { xmlDoc *xmlmap = NULL; xmlDoc *xmldata = NULL; ptzMAP *mapping = NULL; PyObject *pythondata = NULL; // Read XML files xmlmap = xmlReadFile("pythonmap.xml", NULL, 0); xmldata = xmlReadFile("exampledata.xml", NULL, 0); // Parse the mapping XML mapping = dmiMAP_ParseMappingXML(xmlmap, "example_map"); // Parse the xmldata into a Python object pythondata = pythonizeXMLdoc(mapping, xmldata); // ..... the program continues to do something useful } The result stored inside the pythondata object should now be something similar to: {'DemoCase': 'XML Pythonizing', 'String1': 'String value #1', 'AttribString1: 1234, 'TestData': {'Value1': 'More test data', 'ValueList': ['Value1 in list','Value2 in list','Value3 in list']} } --- src/xmlpythonizer.h | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 src/xmlpythonizer.h (limited to 'src/xmlpythonizer.h') diff --git a/src/xmlpythonizer.h b/src/xmlpythonizer.h new file mode 100644 index 0000000..4882d81 --- /dev/null +++ b/src/xmlpythonizer.h @@ -0,0 +1,50 @@ +/* Converts XML docs and nodes to Python dicts and lists by + * using an XML file which describes the Python dict layout + * + * Copyright 2009 David Sommerseth + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * For the avoidance of doubt the "preferred form" of this code is one which + * is in an open unpatent encumbered format. Where cryptographic key signing + * forms part of the process of creating an executable the information + * including keys needed to generate an equivalently functional executable + * are deemed to be part of the source code. + */ + +#ifndef _XMLPYTHONIZER_H +#define _XMLPYTHONIZER_H + +typedef enum ptzTYPES_e { ptzCONST, ptzSTR, ptzINT, ptzFLOAT, + ptzLIST_STR, ptzLIST_INT, ptzLIST_FLOAT, + ptzDICT } ptzTYPES; + +typedef struct ptzMAP_s { + ptzTYPES type_key; // Valid types: ptzCONST, ptzSTR, ptzINT, ptzFLOAT + char *key; // for ptzCONST key contains a static string, other types an XPath to XML data + ptzTYPES type_value; + char *value; // for ptzCONST key contains a static string, + // the rest of types, an XPath to XML data + struct ptzMAP_s *child; // Only used for type_value == pyDICT + struct ptzMAP_s *next; // Pointer chain + +} ptzMAP; + + +ptzMAP *dmiMAP_ParseMappingXML(xmlDoc *xmlmap, const char *mapname); +PyObject *pythonizeXMLdoc(ptzMAP *map, xmlDoc *xmldoc); +PyObject *pythonizeXMLnode(ptzMAP *map, xmlNode *nodes); + +#endif // _XMLPYTHONIZER_H -- cgit From 11691f4b5e5786878cca1d30b183103477d5311f Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Tue, 28 Apr 2009 16:58:33 +0200 Subject: Updated xmlpythonizer to support boolean type and dynamic XPath keys * Added support boolean and list:boolean value types * Traversing child nodes and having dynamic keys Now it is possible to do the following: ** test.xml ** Option 1 Option 2 Option 3 ** mapping.xml ** Which should result in: {'Option 1': True, 'Option 2': False, 'Option 3': True'} --- src/xmlpythonizer.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/xmlpythonizer.h') diff --git a/src/xmlpythonizer.h b/src/xmlpythonizer.h index 4882d81..59cc0cd 100644 --- a/src/xmlpythonizer.h +++ b/src/xmlpythonizer.h @@ -27,8 +27,8 @@ #ifndef _XMLPYTHONIZER_H #define _XMLPYTHONIZER_H -typedef enum ptzTYPES_e { ptzCONST, ptzSTR, ptzINT, ptzFLOAT, - ptzLIST_STR, ptzLIST_INT, ptzLIST_FLOAT, +typedef enum ptzTYPES_e { ptzCONST, ptzSTR, ptzINT, ptzFLOAT, ptzBOOL, + ptzLIST_STR, ptzLIST_INT, ptzLIST_FLOAT, ptzLIST_BOOL, ptzDICT } ptzTYPES; typedef struct ptzMAP_s { -- cgit From 4b925a1433b65c217e787804df3cf349d6b387aa Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Tue, 28 Apr 2009 19:10:45 +0200 Subject: Added filter and filtervalue attributes to xmlpythonizer's tags Using these attributes, only XML data (from the given XPath in 'filter') which matches the value in 'filtervalue' will be added to the Python data. --- src/xmlpythonizer.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/xmlpythonizer.h') diff --git a/src/xmlpythonizer.h b/src/xmlpythonizer.h index 59cc0cd..2c89390 100644 --- a/src/xmlpythonizer.h +++ b/src/xmlpythonizer.h @@ -37,6 +37,10 @@ typedef struct ptzMAP_s { ptzTYPES type_value; char *value; // for ptzCONST key contains a static string, // the rest of types, an XPath to XML data + + char *filter; // Used for simple filtering. If NULL, no filtering is performed + char *filtervalue; // Only XML contents which matches the given value will be parsed further + struct ptzMAP_s *child; // Only used for type_value == pyDICT struct ptzMAP_s *next; // Pointer chain -- cgit From c6baf0a8f50cc19f319ad13ceeb2c40ace0b4d7e Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Wed, 29 Apr 2009 11:18:57 +0200 Subject: Exported ptzmap_Free() --- src/xmlpythonizer.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/xmlpythonizer.h') diff --git a/src/xmlpythonizer.h b/src/xmlpythonizer.h index 2c89390..8572403 100644 --- a/src/xmlpythonizer.h +++ b/src/xmlpythonizer.h @@ -46,8 +46,10 @@ typedef struct ptzMAP_s { } ptzMAP; - ptzMAP *dmiMAP_ParseMappingXML(xmlDoc *xmlmap, const char *mapname); +#define ptzmap_Free(ptr) { ptzmap_Free_func(ptr); ptr = NULL; } +void ptzmap_Free_func(ptzMAP *ptr); + PyObject *pythonizeXMLdoc(ptzMAP *map, xmlDoc *xmldoc); PyObject *pythonizeXMLnode(ptzMAP *map, xmlNode *nodes); -- cgit From 7cf8017a95f04d6207ae3bbf923c8be5d873f6a1 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Wed, 29 Apr 2009 13:07:16 +0200 Subject: Revert "Added filter and filtervalue attributes to xmlpythonizer's tags" This reverts commit 4b925a1433b65c217e787804df3cf349d6b387aa. Discovered that XPath got the needed power for filtering, no need for this extra feature --- src/xmlpythonizer.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src/xmlpythonizer.h') diff --git a/src/xmlpythonizer.h b/src/xmlpythonizer.h index 8572403..770fa66 100644 --- a/src/xmlpythonizer.h +++ b/src/xmlpythonizer.h @@ -37,10 +37,6 @@ typedef struct ptzMAP_s { ptzTYPES type_value; char *value; // for ptzCONST key contains a static string, // the rest of types, an XPath to XML data - - char *filter; // Used for simple filtering. If NULL, no filtering is performed - char *filtervalue; // Only XML contents which matches the given value will be parsed further - struct ptzMAP_s *child; // Only used for type_value == pyDICT struct ptzMAP_s *next; // Pointer chain -- cgit From 94e81cb43908f90ccdeca4d7d459172999d4ae90 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Wed, 13 May 2009 17:39:33 +0200 Subject: Big rewrite of xmlpythonizer - Supports relative XPaths now by using the rootpath attribute in the Map tag. This path is then set for all elements inside this Map tag. - Rewrote the parser to recurse correctly. The former version did not recurse well on the very outer (first) Map level. --- src/xmlpythonizer.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/xmlpythonizer.h') diff --git a/src/xmlpythonizer.h b/src/xmlpythonizer.h index 770fa66..6c61381 100644 --- a/src/xmlpythonizer.h +++ b/src/xmlpythonizer.h @@ -32,6 +32,8 @@ typedef enum ptzTYPES_e { ptzCONST, ptzSTR, ptzINT, ptzFLOAT, ptzBOOL, ptzDICT } ptzTYPES; typedef struct ptzMAP_s { + char *rootpath; // XML root path for the data - if NULL, XML document is the root document. + ptzTYPES type_key; // Valid types: ptzCONST, ptzSTR, ptzINT, ptzFLOAT char *key; // for ptzCONST key contains a static string, other types an XPath to XML data ptzTYPES type_value; -- cgit From a92cc1236ca7c5abee27e4360284b67297e39c15 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 14 May 2009 16:31:34 +0200 Subject: Support fixed size lists When using one of the list types as valuetype, the Map tag now also supports fixedsize and index_attr attributes. - fixedsize : Defines a fixed size of the list - index_attr : Defines an attribute name of the input XML data which contains the list index for the value --- src/xmlpythonizer.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/xmlpythonizer.h') diff --git a/src/xmlpythonizer.h b/src/xmlpythonizer.h index 6c61381..d6fa54c 100644 --- a/src/xmlpythonizer.h +++ b/src/xmlpythonizer.h @@ -39,6 +39,8 @@ typedef struct ptzMAP_s { ptzTYPES type_value; char *value; // for ptzCONST key contains a static string, // the rest of types, an XPath to XML data + int fixed_list_size; // Only to be used on lists + char *list_index ; // Only to be used on fixed lists struct ptzMAP_s *child; // Only used for type_value == pyDICT struct ptzMAP_s *next; // Pointer chain -- cgit From 9d47720a88ee77ac4c0ab5f138a8eaf601c492d0 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 14 May 2009 17:06:18 +0200 Subject: Added new Map attribute - emptyIsNone If the emptyIsNone attribute is set to "1", the Python result will be forced to Py_None if the referenced XML value is empty. When checking if the value is empty, the XML value is right trimmed to remove trailing spaces. Only spaces are are removed. --- src/xmlpythonizer.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/xmlpythonizer.h') diff --git a/src/xmlpythonizer.h b/src/xmlpythonizer.h index d6fa54c..f0efaee 100644 --- a/src/xmlpythonizer.h +++ b/src/xmlpythonizer.h @@ -41,6 +41,8 @@ typedef struct ptzMAP_s { // the rest of types, an XPath to XML data int fixed_list_size; // Only to be used on lists char *list_index ; // Only to be used on fixed lists + int emptyIsNone; // Only for ptzINT/ptzFLOAT values + // - if set to 1, empty input strings sets the result to Py_None struct ptzMAP_s *child; // Only used for type_value == pyDICT struct ptzMAP_s *next; // Pointer chain -- cgit From 72016cb607798e567ac2f2ce67cc50652b0daa32 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Fri, 15 May 2009 11:06:20 +0200 Subject: Added 'emptyValue' attribute in the Map tag This attribute defines a default value when XML source data is empty --- src/xmlpythonizer.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/xmlpythonizer.h') diff --git a/src/xmlpythonizer.h b/src/xmlpythonizer.h index f0efaee..62134b4 100644 --- a/src/xmlpythonizer.h +++ b/src/xmlpythonizer.h @@ -41,8 +41,8 @@ typedef struct ptzMAP_s { // the rest of types, an XPath to XML data int fixed_list_size; // Only to be used on lists char *list_index ; // Only to be used on fixed lists - int emptyIsNone; // Only for ptzINT/ptzFLOAT values - // - if set to 1, empty input strings sets the result to Py_None + int emptyIsNone; // If set to 1, empty input (right trimmed) strings sets the result to Py_None + char *emptyValue; // If set, this value will be used when input is empty struct ptzMAP_s *child; // Only used for type_value == pyDICT struct ptzMAP_s *next; // Pointer chain -- cgit From 599642f7370cb3f2fbf5c079c20269318d5a775f Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Tue, 19 May 2009 15:29:56 +0200 Subject: Added support for value type 'list:dict' for field mapping This builds up a list of dicts. Syntax is: The parser will iterate all nodes defined in the @value attribute and the root path will of the nested mapping will be using the path in @value as the root path for further parsing. --- src/xmlpythonizer.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/xmlpythonizer.h') diff --git a/src/xmlpythonizer.h b/src/xmlpythonizer.h index 62134b4..e659340 100644 --- a/src/xmlpythonizer.h +++ b/src/xmlpythonizer.h @@ -29,7 +29,7 @@ typedef enum ptzTYPES_e { ptzCONST, ptzSTR, ptzINT, ptzFLOAT, ptzBOOL, ptzLIST_STR, ptzLIST_INT, ptzLIST_FLOAT, ptzLIST_BOOL, - ptzDICT } ptzTYPES; + ptzDICT, ptzLIST_DICT } ptzTYPES; typedef struct ptzMAP_s { char *rootpath; // XML root path for the data - if NULL, XML document is the root document. @@ -43,7 +43,7 @@ typedef struct ptzMAP_s { char *list_index ; // Only to be used on fixed lists int emptyIsNone; // If set to 1, empty input (right trimmed) strings sets the result to Py_None char *emptyValue; // If set, this value will be used when input is empty - struct ptzMAP_s *child; // Only used for type_value == pyDICT + struct ptzMAP_s *child; // Only used for type_value == (ptzDICT || ptzLIST_DICT) struct ptzMAP_s *next; // Pointer chain } ptzMAP; -- cgit From 6836d6806f56d83535cf4708907d30b4e56a6974 Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Sun, 24 May 2009 03:48:08 +1000 Subject: Update header file for new function declaration --- src/xmlpythonizer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/xmlpythonizer.h') diff --git a/src/xmlpythonizer.h b/src/xmlpythonizer.h index e659340..2f71dc8 100644 --- a/src/xmlpythonizer.h +++ b/src/xmlpythonizer.h @@ -48,7 +48,7 @@ typedef struct ptzMAP_s { } ptzMAP; -ptzMAP *dmiMAP_ParseMappingXML(xmlDoc *xmlmap, const char *mapname); +ptzMAP *dmiMAP_ParseMappingXML(xmlDoc *xmlmap, xmlDoc *xmltypemap, const char *mapname); #define ptzmap_Free(ptr) { ptzmap_Free_func(ptr); ptr = NULL; } void ptzmap_Free_func(ptzMAP *ptr); -- cgit From 13ff9d7e48ab1574b36473f75701cc7f7c1e461a Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Wed, 27 May 2009 00:11:54 +1000 Subject: WIP commit Merged the two XML files into one, and amended relevant code. I still want to modify the XML tag names, but not yet. The calls to dmidecode.type() not function as expected, but the others are broken - this is next. --- src/xmlpythonizer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/xmlpythonizer.h') diff --git a/src/xmlpythonizer.h b/src/xmlpythonizer.h index 2f71dc8..e659340 100644 --- a/src/xmlpythonizer.h +++ b/src/xmlpythonizer.h @@ -48,7 +48,7 @@ typedef struct ptzMAP_s { } ptzMAP; -ptzMAP *dmiMAP_ParseMappingXML(xmlDoc *xmlmap, xmlDoc *xmltypemap, const char *mapname); +ptzMAP *dmiMAP_ParseMappingXML(xmlDoc *xmlmap, const char *mapname); #define ptzmap_Free(ptr) { ptzmap_Free_func(ptr); ptr = NULL; } void ptzmap_Free_func(ptzMAP *ptr); -- cgit From 3149fdcec94191102fd801c7967a5e3cb5b330a7 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Tue, 2 Jun 2009 15:40:57 +0200 Subject: Rewrote the dmiMAP_ParseMappingXML(...) function and split it up Removed the automagic in the dmiMAP_ParseMappingXML(...) function from automatically decide what to parse (TypeMapping or GroupMapping). Introduced two new functions instead: - dmiMAP_ParseMappingXML_GroupName(xmlDoc *xmlmap, const char *name) Parses the XML mapping document, using the GroupMapping tags and building up a proper ptzMAP structure for all TypeMap defined in that group. - dmiMAP_ParseMappingXML_TypeID(xmlDoc *xmlmap, const char *typeid) Parses the XML mapping document, using only the TypeMapping section in th mapping document. Rewrote a lot of internal parts to reuse as much of the existing code as possible. --- src/xmlpythonizer.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/xmlpythonizer.h') diff --git a/src/xmlpythonizer.h b/src/xmlpythonizer.h index e659340..bda077e 100644 --- a/src/xmlpythonizer.h +++ b/src/xmlpythonizer.h @@ -48,7 +48,8 @@ typedef struct ptzMAP_s { } ptzMAP; -ptzMAP *dmiMAP_ParseMappingXML(xmlDoc *xmlmap, const char *mapname); +ptzMAP *dmiMAP_ParseMappingXML_TypeID(xmlDoc *xmlmap, const char *mapname); +ptzMAP *dmiMAP_ParseMappingXML_GroupName(xmlDoc *xmlmap, const char *mapname); #define ptzmap_Free(ptr) { ptzmap_Free_func(ptr); ptr = NULL; } void ptzmap_Free_func(ptzMAP *ptr); -- cgit From 4b22254e56bfdbec884a7f1cf634e340eff813c5 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Tue, 9 Jun 2009 16:09:22 +0200 Subject: Renamed _dmiMAP_GetRootElement(...) to dmiMAP_GetRootElement(...) and exported the function --- src/xmlpythonizer.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/xmlpythonizer.h') diff --git a/src/xmlpythonizer.h b/src/xmlpythonizer.h index bda077e..f37bfa5 100644 --- a/src/xmlpythonizer.h +++ b/src/xmlpythonizer.h @@ -48,6 +48,7 @@ typedef struct ptzMAP_s { } ptzMAP; +xmlNode *dmiMAP_GetRootElement(xmlDoc *mapdoc); ptzMAP *dmiMAP_ParseMappingXML_TypeID(xmlDoc *xmlmap, const char *mapname); ptzMAP *dmiMAP_ParseMappingXML_GroupName(xmlDoc *xmlmap, const char *mapname); #define ptzmap_Free(ptr) { ptzmap_Free_func(ptr); ptr = NULL; } -- cgit From f9589f45af460c82fac3712b0560de0e1dc6171d Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Tue, 9 Jun 2009 17:14:29 +0200 Subject: Pass typeid as int internally to the dmiMAP_ParseMappingXML_TypeID(...) This function will then convert the value to proper hex value for further processing. --- src/xmlpythonizer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/xmlpythonizer.h') diff --git a/src/xmlpythonizer.h b/src/xmlpythonizer.h index f37bfa5..df60140 100644 --- a/src/xmlpythonizer.h +++ b/src/xmlpythonizer.h @@ -49,7 +49,7 @@ typedef struct ptzMAP_s { } ptzMAP; xmlNode *dmiMAP_GetRootElement(xmlDoc *mapdoc); -ptzMAP *dmiMAP_ParseMappingXML_TypeID(xmlDoc *xmlmap, const char *mapname); +ptzMAP *dmiMAP_ParseMappingXML_TypeID(xmlDoc *xmlmap, int typeid); ptzMAP *dmiMAP_ParseMappingXML_GroupName(xmlDoc *xmlmap, const char *mapname); #define ptzmap_Free(ptr) { ptzmap_Free_func(ptr); ptr = NULL; } void ptzmap_Free_func(ptzMAP *ptr); -- cgit