/** * 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; }