Ejemplo n.º 1
0
/**
 * Takes a stream that is assumed to contain a single complete material
 * definition,
 * reads the definition and produces a new Material object. If many definitions
 * are present then the first one is read
 * @param istr A reference to a stream
 * @return A new Material object
 */
Material MaterialXMLParser::parse(std::istream &istr) const {
  using namespace Poco::XML;
  typedef AutoPtr<Document> DocumentPtr;

  InputSource src(istr);
  DOMParser parser;
  // Do not use auto here or anywhereas the Poco API returns raw pointers
  // but in some circumstances requires AutoPtrs to manage the memory
  DocumentPtr doc;
  try {
    doc = parser.parse(&src);
  } catch (SAXParseException &exc) {
    std::ostringstream os;
    os << "MaterialXMLReader::read() - Error parsing stream as XML: "
       << exc.what();
    throw std::invalid_argument(os.str());
  }

  Element *rootElement = doc->documentElement();

  // Iterating is apparently much faster than getElementsByTagName
  NodeIterator nodeIter(rootElement, NodeFilter::SHOW_ELEMENT);
  Node *node = nodeIter.nextNode();
  Material matr;
  bool found(false);
  while (node) {
    if (node->nodeName() == MATERIAL_TAG) {
      matr = parse(static_cast<Element *>(node));
      found = true;
      break;
    }
    node = nodeIter.nextNode();
  }
  if (!found) {
    throw std::invalid_argument(
        "MaterialXMLReader::read() - No material tags found.");
  }
  return matr;
}