1  #include <string>
  2  #include <sstream>
  3  #include <vector>
  4  #include <xercesc/dom/DOM.hpp>
  5  #include <xercesc/util/XMLString.hpp>
  6  #include <xercesc/util/PlatformUtils.hpp>
  7  
  8  #include "item.h"
  9  
 10  using namespace std;
 11  using namespace xercesc;
 12  
 13  /*
 14    Converts a sequence of XMLCh characters to a string.
 15    @param in the sequence of XMLCh characters
 16    @return the transcoded string
 17  */
 18  string XMLCh_to_string(const XMLCh* in)
 19  {
 20     char* s = XMLString::transcode(in);
 21     string r(s);
 22     XMLString::release(&s);
 23     return r;
 24  }
 25  
 26  /**
 27     Converts a string to a floating-point value, e.g. "3.14" -> 3.14.
 28     @param s a string representing a floating-point value
 29     @return the equivalent floating-point value
 30  */
 31  double string_to_double(string s)
 32  {
 33     istringstream instr(s);
 34     double x;
 35     instr >> x;
 36     return x;
 37  }
 38  
 39  /**
 40     Converts a string to an integer, e.g. "314" -> 314.
 41     @param s a string representing an integer
 42     @return the equivalent integer
 43  */
 44  int string_to_int(string s)
 45  {
 46     istringstream instr(s);
 47     int x;
 48     instr >> x;
 49     return x;
 50  }
 51  
 52  /**
 53     Obtains a product from a DOM element
 54     @param e a <product> element
 55     @return the product described by the given element
 56  */
 57  Product get_product(DOMNode* e)
 58  {
 59     DOMNodeList* children = e->getChildNodes();
 60  
 61     DOMText* textNode
 62        = dynamic_cast<DOMText*>(children->item(0)->getFirstChild());
 63     string name = XMLCh_to_string(textNode->getData());
 64  
 65     textNode
 66        = dynamic_cast<DOMText*>(children->item(1)->getFirstChild());
 67     string price_text = XMLCh_to_string(textNode->getData());
 68     double price = string_to_double(price_text);
 69  
 70     return Product(name, price);
 71  }
 72  
 73  /**
 74     Obtains an item from a DOM element
 75     @param e an <item> element
 76     @return the item described by the given element
 77  */
 78  Item get_item(DOMNode* e)
 79  {
 80     DOMNodeList* children = e->getChildNodes();
 81     Product p = get_product(children->item(0));
 82  
 83     DOMText* textNode = dynamic_cast<DOMText*>(
 84        children->item(1)->getFirstChild());
 85     string quantity_text = XMLCh_to_string(textNode->getData());
 86     int quantity = string_to_int(quantity_text);
 87  
 88     return Item(p, quantity);
 89  }
 90  
 91  /**
 92     Obtains an array list of items from a DOM element
 93     @param e an <items> element
 94     @return a vector of all <item> children of e
 95  */
 96  vector<Item> get_items(DOMNode* e)
 97  {
 98     vector<Item> items;
 99  
100     // get the <item> children
101  
102     DOMNodeList* children = e->getChildNodes();
103     for (int i = 0; i < children->getLength(); i++)
104     {
105        Item c = get_item(children->item(i));
106        items.push_back(c);
107     }
108     return items;
109  }
110  
111  class SimpleErrorHandler : public DOMErrorHandler
112  {
113  public:
114      bool handleError(const DOMError& domError);
115  };
116  
117  bool SimpleErrorHandler::handleError(const DOMError& error)
118  {
119      cout << XMLCh_to_string(error.getLocation()->getURI())
120           << ", line " << error.getLocation()->getLineNumber()
121           << ", char " << error.getLocation()->getColumnNumber()
122           << ": " << XMLCh_to_string(error.getMessage()) << "\n";
123      return error.getSeverity() != DOMError::DOM_SEVERITY_FATAL_ERROR;
124  }
125  
126  int main()
127  {
128     XMLPlatformUtils::Initialize();
129  
130     DOMImplementation* implementation
131        = DOMImplementation::getImplementation();
132     DOMBuilder* parser = implementation->createDOMBuilder(
133        DOMImplementationLS::MODE_SYNCHRONOUS, NULL);
134     DOMErrorHandler* handler = new SimpleErrorHandler();
135     parser->setErrorHandler(handler);
136     parser->setFeature(XMLUni::fgDOMValidation, true);
137     parser->setFeature(XMLUni::fgDOMWhitespaceInElementContent, false);
138     DOMDocument* doc = parser->parseURI("items.xml");
139  
140     DOMNode* root = doc->getDocumentElement();
141     vector<Item> items = get_items(root);
142  
143     for (int i = 0; i < items.size(); i++)
144        items[i].print();
145  
146     parser->release();
147     delete handler;
148  
149     return 0;
150  }