@@ -258,33 +258,87 @@ namespace mtconnect::parser {
258258 DevicePtr XmlParser::parseDevice (const std::string &deviceXml, printer::XmlPrinter *aPrinter)
259259 {
260260 DevicePtr device;
261-
262- using namespace boost ::adaptors;
263- using namespace boost ::range;
264-
265261 std::unique_lock lock (m_mutex);
266262
263+ // Parse the device XML unti an in memory doc and then see if we have a root MTConnectDevices
264+ // node or a Device node. If devices, then we need to find the first device and then use the
265+ // entity parser to parse the device. We then log any errors.
266+
267+ xmlDocPtr doc = nullptr ;
267268 try
268269 {
269- entity::ErrorList errors;
270- auto entity = entity::XmlParser::parse (Device::getRoot (), deviceXml, errors);
271- if (errors.size () > 0 )
270+ xmlInitParser ();
271+ xmlSetGenericErrorFunc (nullptr , agentXMLErrorFunc);
272+
273+ doc = xmlReadMemory (deviceXml.c_str (), int32_t (deviceXml.length ()), " DeviceStream.xml" ,
274+ nullptr , XML_PARSE_NOBLANKS );
275+ if (!doc)
276+ throw runtime_error (" Failed to parse device XML" );
277+
278+ auto root = xmlDocGetRootElement (doc);
279+ if (!root)
280+ throw runtime_error (" Device XML has no root element" );
281+
282+ xmlNodePtr deviceNode = nullptr ;
283+ if (xmlStrcmp (root->name , BAD_CAST " MTConnectDevices" ) == 0 )
272284 {
273- LOG (warning) << " Errors parsing Device: " << deviceXml;
274- for (auto &e : errors)
285+ for (auto child = root->children ; child; child = child->next )
275286 {
276- LOG (warning) << " " << e->what ();
287+ if (xmlStrcmp (child->name , BAD_CAST " Devices" ) == 0 )
288+ {
289+ deviceNode = child->children ;
290+ break ;
291+ }
277292 }
278293 }
294+ else if (xmlStrcmp (root->name , BAD_CAST " Device" ) == 0 )
295+ {
296+ deviceNode = root;
297+ }
279298 else
280299 {
281- device = dynamic_pointer_cast< Device>(entity );
300+ throw runtime_error ( " Root element of device XML must be either MTConnectDevices or Device" );
282301 }
302+
303+ if (!deviceNode)
304+ throw runtime_error (" No Device node found in device XML" );
305+
306+ entity::ErrorList errors;
307+ auto entity = entity::XmlParser::parseXmlNode (Device::getRoot (), deviceNode, errors);
308+
309+ for (auto &e : errors)
310+ {
311+ if (entity)
312+ LOG (warning) << " When parsing device, a problem was skipped: " << e->what ();
313+ else
314+ LOG (error) << " Failed to parse device: " << e->what ();
315+ }
316+
317+ if (entity)
318+ device = dynamic_pointer_cast<Device>(entity);
319+ else
320+ LOG (error) << " Failed to parse device, skipping" ;
321+
322+ xmlFreeDoc (doc);
323+ doc = nullptr ;
324+ }
325+ catch (const runtime_error &e)
326+ {
327+ if (doc)
328+ xmlFreeDoc (doc);
329+ LOG (error) << " Cannot parse device XML: " << e.what ();
283330 }
284331 catch (const string &e)
285332 {
286- LOG (fatal) << " Cannot parse XML document: " << e;
287- throw FatalException ();
333+ if (doc)
334+ xmlFreeDoc (doc);
335+ LOG (error) << " Cannot parse XML document: " << e;
336+ }
337+ catch (...)
338+ {
339+ if (doc)
340+ xmlFreeDoc (doc);
341+ LOG (error) << " Cannot parse XML document: unknown exception" ;
288342 }
289343
290344 return device;
0 commit comments