/* author: jdalbey date: 4/10/2019 */ // Parse the entire Incident XML Script file // Extract the Incidents and Events and create lists of each function parseXml(response) { // Create a parser and grab the high level tag we're interested in var parser = new DOMParser(); var xmlDoc = parser.parseFromString(response,"text/xml"); var eventTags = xmlDoc.getElementsByTagName("SCRIPT_EVENT"); console.log("parsing incident xml file containing "+eventTags.length+" event tags."); // Process each SCRIPT_EVENT tag for (var i = 0; i < eventTags.length; i++) { var currEvt = eventTags[i]; // local variable declarations var timeFields; var evtTime; var incidentNum; var incidentTitle; var cadProp; var telProp; var proparray = new Array(); var evalarray = new Array(); // Process all the children of one event for (var child = 1; child < currEvt.childNodes.length; child++) { // Ignore undefined nodes if (currEvt.childNodes[child].localName != undefined) { var tagName = currEvt.childNodes[child].localName.toUpperCase(); // Determine the tag type and dispatch it for further processing switch(tagName) { case "TIME_INDEX": timeFields = currEvt.childNodes[child].textContent.split(":"); evtTime = new Time(Number(timeFields[0]), Number(timeFields[1]), Number(timeFields[2])); break; case "INCIDENT": /* This tag identifies a new incident. As long as it appears before any other tags, we can use it to create a new incident. (The alternative is to have a separate function that parses xml to extract incidents before we load events.) Creating an event (below) requires that the incident has already been created. */ incidentNum = Number(currEvt.childNodes[child].attributes["LogNum"].value); // If this incident number doesn't exist if (incidents.get(incidentNum) == undefined) { // prepare title field incidentTitle = currEvt.childNodes[child].textContent; // select a color from the pallette var palletteSize = incidents.colorpallette.length; var currColor = incidents.colorpallette[incidents.size()% palletteSize]; //console.log(incidents.size() + " " + incidentNum + " " + currColor); // Construct the incident var theIncident = new Incident(evtTime, incidentNum, incidentTitle, "", currColor); // Add the incident to the list of incidents incidents.add(theIncident); } break; case "GENERAL_INFO": // Add the summary description to the incident var desc = currEvt.childNodes[child].getElementsByTagName("TEXT")[0].textContent; incidentToUpdate = incidents.get(incidentNum); incidentToUpdate.setSummary(desc); // Create an entry showing the Incident start description. Fixes ticket #164 var result = new Array(); result.push("Description:"); result.push(desc); proparray.push(new Property("Incident Start",result)); break; case "CAD_DATA": var caddata = parseCAD(currEvt.childNodes[child]); if (caddata.length > 0) { cadProp = new Property("CHP CAD", caddata ); proparray.push(cadProp); } break; case "TELEPHONE": telProp = new Property("TELEPHONE CONVERSATION", parseTelephone(currEvt.childNodes[child]) ); proparray.push(telProp); break; case "CHP_RADIO": var chpradio = parseCHPradio(currEvt.childNodes[child]); if (chpradio.length > 0) { cadProp = new Property("CHP RADIO", chpradio ); proparray.push(cadProp); } break; case "TMT_RADIO": case "MAINTENANCE_RADIO": var result = new Array(); result.push("Details:"); result.push(currEvt.childNodes[child].textContent.trim()); var radProp = new Property(tagName, result ); proparray.push(radProp); break; case "FACILITATOR_EVALUATION": case "CAD_EVALUATION": case "ATMS_EVALUATION": case "ACTIVITY_LOG_EVALUATION": case "RADIO_EVALUATION": // remove the suffix var evalType = tagName.replace("_EVALUATION",""); // Build the evaluation item var evalItem = new Evaluation(evalType, parseEvaluation(currEvt.childNodes[child]) ); evalarray.push(evalItem); break; case "CMS_EVALUATION": var cmsEval = new Evaluation("CMS", parseCMSEvaluation(currEvt.childNodes[child])); evalarray.push(cmsEval); break; } } }//end one event // console.log(evtTime.format(), incidentNum, proparray.length, evalarray.length); // Ignore Media Log incident and empty nodes if (incidentNum != undefined && incidentNum != 100) { // Create new event with fields obtained from xml file events.add(new Event(evtTime, incidents.get(incidentNum), new Properties(proparray), new Evaluations(evalarray)) ); } }// end all events console.log("Done parsing xml, " + events.length + " events and " +incidents.length + " incidents saved."); // NOW THAT WE HAVE THE EVENT LIST WE CAN PERFORM SETUP setupNotebook(); } function parseCAD(element) { var result = new Array(); var details = element.getElementsByTagName("DETAIL"); if (details.length > 0) { for (detail in details) { if (details[detail].textContent != undefined) { result.push("Detail:"); result.push(details[detail].textContent); } } } return result; } function parseTelephone(element) { var result = new Array(); for (var child = 1; child < element.childNodes.length; child++) { if (element.childNodes[child].localName != undefined) { // IF line is INSTRUCTOR THEN display only the Role field if (element.childNodes[child].localName == "INSTRUCTOR") { result.push(element.childNodes[child].attributes["Role"].value); } else // Display the name (e.g., STUDENT) { result.push(element.childNodes[child].localName); } result.push(element.childNodes[child].textContent); } } return result; } function parseCHPradio(element) { var result = new Array(); var dialog = element.getElementsByTagName("LINE"); if (dialog.length > 0) { for (line in dialog) { if (dialog[line].textContent != undefined) { result.push(dialog[line].attributes["Role"].value); result.push(dialog[line].textContent); } } } return result; } function parseEvaluation(element) { var result = new Array(); var details = element.getElementsByTagName("EXPECTED_ACTION"); if (details.length > 0) { for (detail in details) { if (details[detail].textContent != undefined) { result.push("Expected Action:"); result.push(details[detail].textContent.trim()); } } } return result; } function parseCMSEvaluation(element) { var result = new Array(); var locations = element.getElementsByTagName("LOCATION"); if (locations.length > 0) { result.push("Sign Location:"); result.push(locations[0].textContent); } var details = element.getElementsByTagName("CMS_LINE"); if (details.length > 0) { for (detail in details) { if (details[detail].textContent != undefined) { result.push("Sample Message:"); result.push(details[detail].textContent.trim()); } } } return result; } // MAIN ENTRY POINT for this application function init() { try { // the script must be located where accessible by the web server var scriptFilename = "../dynamicdata/incident_script.xml"; console.log("LoadEvents.js main Attempting to load ", scriptFilename); // Now load the Incident Script and go parse it // NB: This is an async function, so all other notebook setup must be in the callback. loadJSON(scriptFilename, parseXml) } catch(e) { console.log("Error attempting to parse incident script "+response) } }