diff options
author | David Sommerseth <davids@redhat.com> | 2009-04-28 19:10:45 +0200 |
---|---|---|
committer | David Sommerseth <davids@redhat.com> | 2009-04-29 11:22:12 +0200 |
commit | 4b925a1433b65c217e787804df3cf349d6b387aa (patch) | |
tree | 11a32b038eb36a442aa0d9594c531a9f1a8676e3 /src | |
parent | 11691f4b5e5786878cca1d30b183103477d5311f (diff) | |
download | python-dmidecode-4b925a1433b65c217e787804df3cf349d6b387aa.tar.gz python-dmidecode-4b925a1433b65c217e787804df3cf349d6b387aa.tar.xz python-dmidecode-4b925a1433b65c217e787804df3cf349d6b387aa.zip |
Added filter and filtervalue attributes to xmlpythonizer's <Map> 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.
Diffstat (limited to 'src')
-rw-r--r-- | src/xmlpythonizer.c | 86 | ||||
-rw-r--r-- | src/xmlpythonizer.h | 4 |
2 files changed, 78 insertions, 12 deletions
diff --git a/src/xmlpythonizer.c b/src/xmlpythonizer.c index 594717c..32f0181 100644 --- a/src/xmlpythonizer.c +++ b/src/xmlpythonizer.c @@ -40,6 +40,7 @@ ptzMAP *ptzmap_Add(const ptzMAP *chain, ptzTYPES ktyp, const char *key, ptzTYPES vtyp, const char *value, + const char *filter, const char *filterval, ptzMAP *child) { ptzMAP *ret = NULL; @@ -65,6 +66,11 @@ ptzMAP *ptzmap_Add(const ptzMAP *chain, ret->child = child; } + if( filter != NULL && filterval != NULL ) { + ret->filter = strdup(filter); + ret->filtervalue = strdup(filterval); + } + if( chain != NULL ) { ret->next = (ptzMAP *) chain; } @@ -86,6 +92,16 @@ void ptzmap_Free_func(ptzMAP *ptr) ptr->value = NULL; } + if( ptr->filter != NULL ) { + free(ptr->filter); + ptr->filter = NULL; + } + + if( ptr->filtervalue != NULL ) { + free(ptr->filtervalue); + ptr->filtervalue = NULL; + } + if( ptr->child != NULL ) { ptzmap_Free(ptr->child); } @@ -125,6 +141,10 @@ void ptzmap_Dump_func(const ptzMAP *ptr, int level) ptr->type_key, ptzTYPESstr[ptr->type_key], ptr->key); indent(level); printf("value type: (%i) %-13.13s - value: %s\n", ptr->type_value, ptzTYPESstr[ptr->type_value], ptr->value); + if( ptr->filter != NULL ) { + indent(level); printf("filter: %s == %s\n", ptr->filter, ptr->filtervalue); + } + if( ptr->child != NULL ) { indent(level); printf(" ** CHILD\n"); ptzmap_Dump_func(ptr->child, level + 1); @@ -200,6 +220,7 @@ ptzMAP *_do_dmimap_parsing(xmlNode *node) { for( ptr_n = map_n ; ptr_n != NULL; ptr_n = ptr_n->next ) { ptzTYPES type_key, type_value; char *key = NULL, *value = NULL; + char *filter = NULL, *filterval = NULL; if( ptr_n->type != XML_ELEMENT_NODE ) { continue; @@ -212,6 +233,12 @@ ptzMAP *_do_dmimap_parsing(xmlNode *node) { value = dmixml_GetAttrValue(ptr_n, "value"); type_value = _convert_maptype(dmixml_GetAttrValue(ptr_n, "valuetype")); + // Get filters + filter = dmixml_GetAttrValue(ptr_n, "filter"); + if( filter != NULL ) { + filterval = dmixml_GetAttrValue(ptr_n, "filtervalue"); + } + if( type_value == ptzDICT ) { // When value type is ptzDICT, traverse the children nodes // - should contain another Map set instead of a value attribute @@ -219,12 +246,18 @@ ptzMAP *_do_dmimap_parsing(xmlNode *node) { continue; } // Recursion - retmap = ptzmap_Add(retmap, type_key, key, type_value, NULL, + retmap = ptzmap_Add(retmap, type_key, key, + type_value, NULL, + filter, filterval, _do_dmimap_parsing(ptr_n->children->next)); + } else { // Append the value as a normal value when the // value type is not a Python Dict - retmap = ptzmap_Add(retmap, type_key, key, type_value, value, NULL); + retmap = ptzmap_Add(retmap, type_key, key, + type_value, value, + filter, filterval, + NULL); } value = NULL; key = NULL; @@ -272,7 +305,6 @@ ptzMAP *dmiMAP_ParseMappingXML(xmlDoc *xmlmap, const char *mapname) { // Start creating an internal map structure based on the mapping XML. map = _do_dmimap_parsing(node); - return map; } @@ -369,12 +401,42 @@ inline char *_get_key_value(ptzMAP *map_p, xmlXPathContext *xpctx, int idx) { } -#define PyADD_DICT_VALUE(p, k, v) { \ - if( k != NULL ) { \ - PyDict_SetItemString(p, k, v); \ - Py_DECREF(v); \ - } \ +void _register_value(PyObject *pyobj, xmlXPathContext *xpctx, + ptzMAP *map_p, const char *key, PyObject *value) +{ + if( key != NULL ) { + if( (map_p->filter != NULL) && (map_p->filtervalue != NULL) ) { + xmlXPathObject *xpobj = NULL; + int i = 0, found = 0; + + xpobj = _get_xpath_values(xpctx, map_p->filter); + if( (xpobj == NULL) || (xpobj->nodesetval->nodeNr < 1) ) { + // If node not found, or our value index is higher + // than what we found, filter it out. + if( xpobj != NULL ) { + xmlXPathFreeObject(xpobj); + } + return; + } + + for( i = 0; i < xpobj->nodesetval->nodeNr; i++ ) { + if( strcmp(map_p->filtervalue, + dmixml_GetContent(xpobj->nodesetval->nodeTab[i])) == 0 ) { + found = 1; + break; + } + } + + if( found != 1 ) { + // If value did not match - no hit => do not add value + xmlXPathFreeObject(xpobj); + return; + } + } + PyDict_SetItemString(pyobj, key, value); + Py_DECREF(value); } +} // Internal XML parser routine, which traverses the given mapping table, // returning a Python structure accordingly to the map. @@ -394,7 +456,7 @@ PyObject *_do_pythonizeXML(ptzMAP *in_map, xmlXPathContext *xpctx, int lvl) { case ptzCONST: value = PyString_FromString(map_p->value); key = _get_key_value(map_p, xpctx, 0); - PyADD_DICT_VALUE(retdata, key, value); + _register_value(retdata, xpctx, map_p, key, value); break; @@ -408,7 +470,7 @@ PyObject *_do_pythonizeXML(ptzMAP *in_map, xmlXPathContext *xpctx, int lvl) { 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); + _register_value(retdata, xpctx, map_p, key, value); } xmlXPathFreeObject(xpobj); } @@ -427,7 +489,7 @@ PyObject *_do_pythonizeXML(ptzMAP *in_map, xmlXPathContext *xpctx, int lvl) { } xmlXPathFreeObject(xpobj); key = _get_key_value(map_p, xpctx, 0); - PyADD_DICT_VALUE(retdata, key, value); + _register_value(retdata, xpctx, map_p, key, value); } break; @@ -437,7 +499,7 @@ PyObject *_do_pythonizeXML(ptzMAP *in_map, xmlXPathContext *xpctx, int lvl) { Py_DECREF(value); key = _get_key_value(map_p, xpctx, 0); - PyADD_DICT_VALUE(retdata, key, value); + _register_value(retdata, xpctx, map_p, key, value); break; default: 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 |