summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Sommerseth <davids@redhat.com>2009-04-28 19:10:45 +0200
committerDavid Sommerseth <davids@redhat.com>2009-04-29 11:22:12 +0200
commit4b925a1433b65c217e787804df3cf349d6b387aa (patch)
tree11a32b038eb36a442aa0d9594c531a9f1a8676e3 /src
parent11691f4b5e5786878cca1d30b183103477d5311f (diff)
downloadpython-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.c86
-rw-r--r--src/xmlpythonizer.h4
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