diff options
author | David Sommerseth <davids@redhat.com> | 2009-04-28 16:58:33 +0200 |
---|---|---|
committer | David Sommerseth <davids@redhat.com> | 2009-04-29 11:22:12 +0200 |
commit | 11691f4b5e5786878cca1d30b183103477d5311f (patch) | |
tree | 2f5d0d65e3a0f23622fcca4f367edb7ddc90fe32 /src | |
parent | c7be629d44d4e2be6c8116796714e0042a977885 (diff) | |
download | python-dmidecode-11691f4b5e5786878cca1d30b183103477d5311f.tar.gz python-dmidecode-11691f4b5e5786878cca1d30b183103477d5311f.tar.xz python-dmidecode-11691f4b5e5786878cca1d30b183103477d5311f.zip |
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 **
<?xml version="1.0" encoding="UTF-8"?>
<testdata>
<list>
<value enabled="1">Option 1</value>
<value enabled="0">Option 2</value>
<value enabled="1">Option 3</value>
</list>
</testdata>
** mapping.xml **
<?xml version="1.0" encoding="UTF-8"?>
<dmidecode_fieldmap version="1">
<Mapping name="example">
<Map keytype="string" key="/testdata/list/value"
valuetype="boolean" value="/testdata/list/value/@enabled"/>
</Mapping>
</dmidecode_fieldmap>
Which should result in:
{'Option 1': True, 'Option 2': False, 'Option 3': True'}
Diffstat (limited to 'src')
-rw-r--r-- | src/xmlpythonizer.c | 121 | ||||
-rw-r--r-- | src/xmlpythonizer.h | 4 |
2 files changed, 88 insertions, 37 deletions
diff --git a/src/xmlpythonizer.c b/src/xmlpythonizer.c index 92e0d7f..594717c 100644 --- a/src/xmlpythonizer.c +++ b/src/xmlpythonizer.c @@ -96,10 +96,10 @@ void ptzmap_Free_func(ptzMAP *ptr) } -#if 1 +#if 0 // DEBUG FUNCTIONS -static const char *ptzTYPESstr[] = { "ptzCONST", "ptzSTR", "ptzINT", "ptzFLOAT", - "ptzLIST_STR", "ptzLIST_INT", "ptzLIST_FLOAT", +static const char *ptzTYPESstr[] = { "ptzCONST", "ptzSTR", "ptzINT", "ptzFLOAT", "ptzBOOL", + "ptzLIST_STR", "ptzLIST_INT", "ptzLIST_FLOAT", "ptzLIST_BOOL", "ptzDICT", NULL }; void indent(int lvl) @@ -155,12 +155,16 @@ inline ptzTYPES _convert_maptype(const char *str) { return ptzINT; } else if( strcmp(str, "float") == 0 ) { return ptzFLOAT; + } else if( strcmp(str, "boolean") == 0 ) { + return ptzBOOL; } else if( strcmp(str, "list:string") == 0 ) { return ptzLIST_STR; } else if( strcmp(str, "list:integer") == 0 ) { return ptzLIST_INT; } else if( strcmp(str, "list:float") == 0 ) { return ptzLIST_FLOAT; + } else if( strcmp(str, "list:boolean") == 0 ) { + return ptzLIST_BOOL; } else if( strcmp(str, "dict") == 0 ) { return ptzDICT; } else { @@ -280,15 +284,24 @@ ptzMAP *dmiMAP_ParseMappingXML(xmlDoc *xmlmap, const char *mapname) { inline PyObject *StringToPyObj(ptzTYPES type, const char *str) { PyObject *value; + if( str == NULL ) { + return Py_None; + } + switch( type ) { case ptzINT: case ptzLIST_INT: - value = PyInt_FromLong((str != NULL ? atoi(str) : 0)); + value = PyInt_FromLong(atoi(str)); break; case ptzFLOAT: case ptzLIST_FLOAT: - value = PyFloat_FromDouble((str != NULL ? atof(str) : 0)); + value = PyFloat_FromDouble(atof(str)); + break; + + case ptzBOOL: + case ptzLIST_BOOL: + value = PyBool_FromLong((atoi(str) == 1 ? 1:0)); break; case ptzSTR: @@ -326,6 +339,43 @@ xmlXPathObject *_get_xpath_values(xmlXPathContext *xpctx, const char *xpath) { return xp_obj; } +inline char *_get_key_value(ptzMAP *map_p, xmlXPathContext *xpctx, int idx) { + char *key = NULL; + xmlXPathObject *xpobj = NULL; + + switch( map_p->type_key ) { + case ptzCONST: + key = map_p->key; + break; + + case ptzSTR: + case ptzINT: + case ptzFLOAT: + xpobj = _get_xpath_values(xpctx, map_p->key); + if( xpobj != NULL ) { + key = dmixml_GetContent(xpobj->nodesetval->nodeTab[idx]); + xmlXPathFreeObject(xpobj); + } + break; + + default: + fprintf(stderr, "Unknown key type: %i\n", map_p->type_key); + break; + } + if( key == NULL ) { + fprintf(stderr, "Could not find the key value: %s\n", map_p->key); + } + return key; +} + + +#define PyADD_DICT_VALUE(p, k, v) { \ + if( k != NULL ) { \ + PyDict_SetItemString(p, k, v); \ + Py_DECREF(v); \ + } \ + } + // Internal XML parser routine, which traverses the given mapping table, // returning a Python structure accordingly to the map. PyObject *_do_pythonizeXML(ptzMAP *in_map, xmlXPathContext *xpctx, int lvl) { @@ -339,40 +389,27 @@ PyObject *_do_pythonizeXML(ptzMAP *in_map, xmlXPathContext *xpctx, int lvl) { char *key = NULL; PyObject *value = NULL; - // Get key value - switch( map_p->type_key ) { - case ptzCONST: - key = map_p->key; - break; - - case ptzSTR: - case ptzINT: - case ptzFLOAT: - xpobj = _get_xpath_values(xpctx, map_p->key); - if( xpobj != NULL ) { - key = dmixml_GetContent(xpobj->nodesetval->nodeTab[0]); - xmlXPathFreeObject(xpobj); - } - break; - default: - fprintf(stderr, "Unknown key type: %i\n", map_p->type_key); - return Py_None; - break; - } - // Get 'value' value switch( map_p->type_value ) { case ptzCONST: value = PyString_FromString(map_p->value); + key = _get_key_value(map_p, xpctx, 0); + PyADD_DICT_VALUE(retdata, key, value); + break; case ptzSTR: case ptzINT: case ptzFLOAT: + case ptzBOOL: xpobj = _get_xpath_values(xpctx, map_p->value); if( xpobj != NULL ) { - value = StringToPyObj(map_p->type_value, - dmixml_GetContent(xpobj->nodesetval->nodeTab[0])); + for( i = 0; i < xpobj->nodesetval->nodeNr; i++ ) { + value = StringToPyObj(map_p->type_value, + dmixml_GetContent(xpobj->nodesetval->nodeTab[i])); + key = _get_key_value(map_p, xpctx, i); + PyADD_DICT_VALUE(retdata, key, value); + } xmlXPathFreeObject(xpobj); } break; @@ -380,6 +417,7 @@ PyObject *_do_pythonizeXML(ptzMAP *in_map, xmlXPathContext *xpctx, int lvl) { case ptzLIST_STR: case ptzLIST_INT: case ptzLIST_FLOAT: + case ptzLIST_BOOL: xpobj = _get_xpath_values(xpctx, map_p->value); value = PyList_New(0); if( xpobj != NULL ) { @@ -388,6 +426,8 @@ PyObject *_do_pythonizeXML(ptzMAP *in_map, xmlXPathContext *xpctx, int lvl) { PyList_Append(value, StringToPyObj(map_p->type_value, valstr)); } xmlXPathFreeObject(xpobj); + key = _get_key_value(map_p, xpctx, 0); + PyADD_DICT_VALUE(retdata, key, value); } break; @@ -395,17 +435,16 @@ PyObject *_do_pythonizeXML(ptzMAP *in_map, xmlXPathContext *xpctx, int lvl) { // Traverse the children to get the value of this element value = _do_pythonizeXML(map_p->child, xpctx, lvl+1); Py_DECREF(value); + + key = _get_key_value(map_p, xpctx, 0); + PyADD_DICT_VALUE(retdata, key, value); break; default: fprintf(stderr, "Unknown value type: %i\n", map_p->type_value); - free(key); key = NULL; return Py_None; break; } - - PyDict_SetItemString(retdata, key, value); - Py_DECREF(value); } Py_INCREF(retdata); return retdata; @@ -457,16 +496,28 @@ PyObject *pythonizeXMLnode(ptzMAP *map, xmlNode *nodes) #if 0 // Simple independent main function - only for debugging int main() { - xmlDoc *doc = NULL; + xmlDoc *doc = NULL, *data = NULL; ptzMAP *map = NULL; + PyObject *pydat = NULL; doc = xmlReadFile("pythonmap.xml", NULL, 0); assert( doc != NULL ); - map = dmiMAP_ParseMappingXML(doc, "BIOSLanguage"); + map = dmiMAP_ParseMappingXML(doc, "bios"); ptzmap_Dump(map); + printf("----------------------\n"); + + + data = xmlReadFile("test.xml", NULL, 0); + assert( data != NULL ); + + pydat = pythonizeXMLdoc(map, data); + Py_INCREF(pydat); + PyObject_Print(pydat, stdout, 0); + Py_DECREF(pydat); ptzmap_Free(map); + xmlFreeDoc(data); xmlFreeDoc(doc); return 0; @@ -485,7 +536,7 @@ PyObject* demo_xmlpy() mapping_xml = xmlReadFile("pythonmap.xml", NULL, 0); assert( mapping_xml != NULL ); - mapping = dmiMAP_ParseMappingXML(mapping_xml, "BIOSLanguage"); + mapping = dmiMAP_ParseMappingXML(mapping_xml, "bios"); assert( mapping != NULL ); // Read XML data from file 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 { |