SMBIOS Library
XmlUtils.cpp
Go to the documentation of this file.
1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2  * vim:expandtab:autoindent:tabstop=4:shiftwidth=4:filetype=c:cindent:textwidth=0:
3  *
4  * Copyright (C) 2005 Dell Inc.
5  * by Michael Brown <Michael_E_Brown@dell.com>
6  * Licensed under the Open Software License version 2.1
7  *
8  * Alternatively, you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published
10  * by the Free Software Foundation; either version 2 of the License,
11  * or (at your option) any later version.
12 
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16  * See the GNU General Public License for more details.
17  */
18 
19 #define LIBSMBIOS_SOURCE
20 #include "XmlUtils.h"
21 
22 using namespace std;
23 
24 #if defined(DEBUG_XMLUTILS)
25 #include <iostream>
26 # define DCOUT(line) do { cout << line; } while(0)
27 # define DCERR(line) do { cerr << line; } while(0)
28 #else
29 # define DCOUT(line) do {} while(0)
30 # define DCERR(line) do {} while(0)
31 #endif
32 
33 namespace xmlutils
34 {
35  //
36  // NON-MEMBER FUNCTIONS
37  //
38  DOMBuilder *getParser() { return 0; }
39 
40  // backwards compat for libxml < 2.6 without xmlReadFile()
41  void suppressLibxmlWarnings (void *ctx, const char *msg, ...)
42  {
45  }
46 
47  // the best. use this when possible.
48  string safeGetAttribute( const xmlNode *node, const string &attr )
49  {
50  string retval("");
51  xmlChar *text = xmlGetProp(const_cast<xmlNode *>(node), reinterpret_cast<const xmlChar *>(attr.c_str()));
52  if (text)
53  retval = reinterpret_cast<const char *>(text);
54  xmlFree(text);
55  return retval;
56  }
57 
58  //
59  // Finds a "STRUCTURE" element with the specified attribute and returns
60  // a pointer to it.
61  //
62  xmlNodePtr findElement( xmlNodePtr root, const string elementName, const string &attribute, const string &value )
63  {
64  xmlNodePtr elem = 0;
65  DCERR("findElement( root, " << "\"" << elementName << "\", \"" << attribute << "\", \"" << value << "\");" << endl);
66 
67  // If we don't have a ref to XML file, we cannot find this info
68  if( ! root )
69  throw NotFoundImpl("no root element ref to xml file, cannot findElement");
70 
71  xmlNodePtr cur_node = NULL;
72  for (cur_node = root; cur_node; cur_node = cur_node->next) {
73  DCERR("\tnode type: Element, name: " << cur_node->name << endl);
74  if (cur_node->type == XML_ELEMENT_NODE) {
75  if (!xmlStrcmp(cur_node->name, reinterpret_cast<const xmlChar *>(elementName.c_str())))
76  {
77  string strAttrValue = safeGetAttribute( cur_node, attribute );
78  DCERR("\tELEMENT attribute ("<< attribute <<") value: " << "\"" << strAttrValue << "\"" << endl);
79  if( (strAttrValue == value) || (attribute == "") )
80  {
81  DCERR("MATCH!" << endl);
82  elem = cur_node;
83  goto out;
84  }
85  }
86  }
87  try
88  {
89  DCERR("\tsearching child: " << cur_node->name << endl);
90  elem = findElement(cur_node->children, elementName, attribute, value);
91  goto out;
92  }
93  catch (NotFound)
94  {
95  // not an error yet
96  DCERR("\tDid not find match in child: " << cur_node->name << endl);
97  }
98  }
99 
100 out:
101  if (!elem)
102  {
103  DCERR("Throwing not found error!"<< endl);
104  throw NotFoundImpl("could not find element.");
105  }
106 
107  return elem;
108  }
109 
110 
111  //
112  // Finds a "STRUCTURE" element with the specified attribute and returns
113  // a pointer to it.
114  //
115  xmlNodePtr findElement( xmlNodePtr root, const string elementName, const string &attribute, long value)
116  {
117  xmlNodePtr elem = 0;
118 
119  DCERR("findElement( root, " << "\"" << elementName << "\", \"" << attribute << "\", \"" << value << "\");" << endl);
120 
121  // If we don't have a ref to XML file, we cannot find this info
122  if( ! root )
123  throw NotFoundImpl("no root element ref to xml file, cannot findElement");
124 
125  xmlNodePtr cur_node = NULL;
126  for (cur_node = root; cur_node; cur_node = cur_node->next) {
127  DCERR("\tnode type: Element, name: " << cur_node->name << endl);
128  if (cur_node->type == XML_ELEMENT_NODE) {
129  if (!xmlStrcmp(cur_node->name, reinterpret_cast<const xmlChar *>(elementName.c_str())))
130  {
131  // printf("node type: Element, name: %s\n", cur_node->name);
132  string strAttrValue = safeGetAttribute( cur_node, attribute );
133  char *endptr = 0;
134  long attrValue = strtol(strAttrValue.c_str(), &endptr, 0);
135  DCERR("\tELEMENT attribute ("<< attribute <<") value: " << "\"" << strAttrValue << "\"" << endl);
136  if(endptr != strAttrValue.c_str())
137  if( (attrValue == value) || (attribute == "") )
138  {
139  DCERR("MATCH!" << endl);
140  elem = cur_node;
141  goto out;
142  }
143  }
144  }
145  try
146  {
147  DCERR("\tsearching child: " << cur_node->name << endl);
148  elem = findElement(cur_node->children, elementName, attribute, value);
149  goto out;
150  }
151  catch (NotFound) {} // not an error yet
152  }
153 
154 out:
155  if (!elem)
156  {
157  DCERR("Throwing not found error!"<< endl);
158  throw NotFoundImpl("could not find element.");
159  }
160 
161  return elem;
162  }
163 
164  xmlNodePtr findElementWithNumericAttr( xmlNodePtr root, const string elementName, const string &attribute, long value)
165  {
166  return findElement(root, elementName, attribute, value);
167  }
168 
169  string getNodeText( xmlNodePtr elem )
170  {
171  string retval = "";
172  xmlChar *text = 0;
173  text = xmlNodeGetContent(elem);
174  retval = reinterpret_cast<const char *>(text);
175  xmlFree(text);
176  return retval;
177  }
178 
179 
180  int getNumberFromXmlAttr( xmlNodePtr element, const string field, int base )
181  {
182  int tempNum = 0;
183  string tempStr = safeGetAttribute( element, field );
184  if(tempStr.length() != 0)
185  tempNum = strtol( tempStr.c_str(), 0, base);
186 
187  return tempNum;
188  }
189 }