XML data to HashMap - javascript

I need to store XML data to a hashmap, I'm using nodejs and xmldom npm module to parse the XML.
I'm trying to store the testsuite name, testcase name and dt_value in a hashmap.
here is my XML code
<testscenario>
<testsuite name="com.edge.route">
<testcase name="tc_Login">dt_Login</testcase>
<testcase name="tc_Logout">dt_Logout</testcase>
</testsuite>
<testsuite name="com.edge.beacon">
<testcase name="tc_Channel">dt_Channel,dt_Logout</testcase>
</testsuite>
</testscenario>
Here's what I have tried so far
var DOMParser = require('xmldom').DOMParser;
var parser = new DOMParser();
var HashMap = require('hashmap');
var fs = require('fs');
module.exports = {
testScenario: function() {
var suiteName;
var data;
var map = new HashMap();
//read the testscenario.xml
data = fs.readFileSync("./testscenario.xml", "utf8");
var dom = parser.parseFromString(data);
var testSuiteList = dom.getElementsByTagName("testsuite");
//loop through all the test suites
for (i = 0; i < testSuiteList.length; i++) {
//select the test suite with the given name
suiteName = testSuiteList[i].getAttribute("name");
var tcList = testSuiteList[i].getElementsByTagName("testcase");
var dtList = testSuiteList[i].getElementsByTagName("testcase")[0].childNodes[0].nodeValue;
console.log(dtList)
//get the row count
tcLength = tcList.length;
//push column headers as the key in the hashmamp
var testCaseList = [];
for (x = 0; x < tcList.length; x++) {
testCaseList.push(tcList[x].getAttribute("name"));
}
console.log(testCaseList)
var dataTableList = [];
for (i = 0; i < tcLength; i++) {
dataTableList += tcList[i].childNodes[0].nodeValue;
}
console.log("dtlist = " + dataTableList);
//push the row values as an array to the hashmap
map.set(suiteName, testCaseList);
}
return [map]
}
};
I'm able to get the key, value pair for testsuite and testcase but I also need to get the dt_name. how can I modify this code to store the dt_name along with testsuite and testcase names in that hashmap?

Alright figured it out. This is how I did it. I have used a hashmap within a hashmap
//XML Reader
var DOMParser = require('xmldom').DOMParser;
var parser = new DOMParser();
var HashMap = require('hashmap');
var fs = require('fs');
module.exports={
testScenario: function ()
{
var suiteName;
var data;
var map = new HashMap();
//read the testscenario.xml
data=fs.readFileSync("./testscenario.xml","utf8");
var dom = parser.parseFromString(data);
var testSuiteList = dom.getElementsByTagName("testsuite");
//loop through all the test suites
for (i=0;i< testSuiteList.length; i++) {
//select the test suite with the given name
suiteName = testSuiteList[i].getAttribute("name");
var tcList = testSuiteList[i].getElementsByTagName("testcase");
//get the row count
Length=tcList.length;
//push column headers as the key in the hashmamp
var testCaseList = new HashMap();
for(x=0;x<Length;x++)
{
testCaseList.set(tcList[x].getAttribute("name"),tcList[x].childNodes[0].nodeValue);
}
//push the row values as an array to the hashmap
map.set(suiteName,testCaseList);
}
return [map]
}
};

Related

.length not working on array in Google Apps Script

I have this code. I want to loop through the array and create a new doc for each entry. If I manually set the loop length to the number of rows it works fine. I want to set it to loop for the length of the array. However the .length property always returns null. What am I missing. I have also tried for each loops with no luck.
function createDocument()
{
//var headers = Sheets.Spreadsheets.Values.get('fileID', 'A1:Z1');
var studentHistory = Sheets.Spreadsheets.Values.get('fileID', 'A2:Z200');
var templateId = 'fileID';
var documentId;
var dstFolder = DriveApp.getFolderById('folderID');
var length = studentHistory.length;
Logger.log(studentHistory);
Logger.log(length);
//Loop through rows in sheet
for (var i = 0; i < length; i++){
//Get values from sheet row
var date = studentHistory.values[i][0];
var studentName = studentHistory.values[i][1];
var dob = studentHistory.values[i][2];
var pcDoctor = studentHistory.values[i][3];
var address = studentHistory.values[i][4];
var fgName = studentHistory.values[i][5];
var mgName = studentHistory.values[i][6];
var phoneMom = studentHistory.values[i][7];
var phoneDad = studentHistory.values[i][8];
var empMom = studentHistory.values[i][9];
var empDad = studentHistory.values[i][10];
var livesWith = studentHistory.values[i][11];
var childrenInHome = studentHistory.values[i][12];
var childrenNotInHome = studentHistory.values[i][13];
var othersInHome = studentHistory.values[i][14];
var illnesses = studentHistory.values[i][15];
var illnessDetails = studentHistory.values[i][16];
var hospitalizations = studentHistory.values[i][17];
var hospDetails = studentHistory.values[i][18];
var trauma = studentHistory.values[i][19];
var traumaDetails = studentHistory.values[i][20];
var injuries = studentHistory.values[i][21];
var injuryDetails = studentHistory.values[i][22];
var medications = studentHistory.values[i][23];
var additionalComments = studentHistory.values[i][24];
var otherSchools = studentHistory.values[i][25];
//Make a copy of the template file
documentId = DriveApp.getFileById(templateId).makeCopy(dstFolder).getId();
//Change name of newly created document
DriveApp.getFileById(documentId).setName('SocialHistory_' + studentName + '_' + date);
var body = DocumentApp.openById(documentId).getBody();
//Insert values
body.replaceText('<<date>>', date);
body.replaceText('<<studentName>>', studentName);
body.replaceText('<<dob>>', dob);
body.replaceText('<<pcDoctor>>', pcDoctor);
body.replaceText('<<address>>', address);
body.replaceText('<<fgName>>', fgName);
body.replaceText('<<mgName>>', mgName);
body.replaceText('<<phoneMom>>', phoneMom);
body.replaceText('<<phoneDad>>', phoneDad);
body.replaceText('<<empMom>>', empMom);
body.replaceText('<<empDad>>', empDad);
body.replaceText('<<livesWithe>>', livesWith);
body.replaceText('<<childrenInHome>>', childrenInHome);
body.replaceText('<<childrenNotInHome>>', childrenNotInHome);
body.replaceText('<<othersInHome>>', othersInHome);
body.replaceText('<<illnesses>>', illnesses);
body.replaceText('<<illnessDetails>>', illnessDetails);
body.replaceText('<<hospitalizations>>', hospitalizations);
body.replaceText('<<hospDetails>>', hospDetails);
body.replaceText('<<trauma>>', trauma);
body.replaceText('<<traumaDetails>>', traumaDetails);
body.replaceText('<<injuries>>', injuries);
body.replaceText('<<injuryDetails>>', injuryDetails);
body.replaceText('<<medications>>', medications);
body.replaceText('<<additionalComments>>', additionalComments);
body.replaceText('<<otherSchools>>', otherSchools);
}
}
studentHistory.values is the array.
Therefore, try this instead to get the length:
var length = studentHistory.values.length;
Solution
I see you are using Advanced Google Services to call the Sheets API. This Apps Script class allows you to call the Google APIs directly from your script handling automatically the authorization process.
However it doesn't work as the built in Classes that are available for example inside the SpreadsheetApp wrapper.
Your request will return an HTTP-like response following these specifications:
{
"range": string,
"majorDimension": enum (Dimension),
"values": [
array
]
}
You will need to parse these responses in order to achieve the desired result.
Proposed modification
function createDocument()
{
//var headers = Sheets.Spreadsheets.Values.get('fileID', 'A1:Z1');
var studentHistory = Sheets.Spreadsheets.Values.get('fileID', 'A2:Z200');
var templateId = 'fileID';
var documentId;
var dstFolder = DriveApp.getFolderById('folderID');
var length = studentHistory.values.length;
...
Reference
Google Sheets API
Advanced Google Services

Using exceljs and trying to make local vars in readfile function global

Hi I am using exceljs with JavaScript for my project but all of the variable that I modify within the readFile function are not changing outside scope.
//array for pdm paths
var arrFundPartyRole = [];
//mapping UI_id -> UI_Label
var labelUIMap = new Map();
//xlsx parsing to get necessary data
var workbook = new Excel.Workbook();
workbook.xlsx.readFile('Veritas_Full_082819.xlsx')
.then(function() {
//getting the worksheet and necessary columns
var worksheet = workbook.getWorksheet('VT_FULL');
var pdmPath = worksheet.getColumn(18);
var idUI = worksheet.getColumn(24);
var labelUI = worksheet.getColumn(27);
//iterate over all pdm paths by column
pdmPath.eachCell(function(cell, rowNumber) {
var path = cell.value;
if (path != null) {
//splitting the path
var pathElts = path.split(".");
if (pathElts[0] == 'FundPartyRole') {
arrFundPartyRole.push(pathElts);
}
}
});
//iterate over the UI_id column and find corresponding label
//counter to skip the first 2 columns?
var counter = 0;
idUI.eachCell(function(cell, rowNumber) {
if ((cell.value != null) && (counter > 1)) {
var idAddress = cell.address;
//address of id can be used to create address of label
var labelAddress = idAddress.replace("X", "AA");
var label = worksheet.getCell(labelAddress).value;
labelUIMap.set(cell.value, label);
}
counter = counter + 1;
});
/*for (i = 0; i < arrFundPartyRole.length; i++) {
if labelUIMap.get()
}*/
console.log(labelUIMap);
});
console.log(labelUIMap);
In this case, labelUIMap and arrFundPartyRole are blank when I print them outside scope but populated within the scope. Am I missing something?
You have to add after the first console.log(labelUIMap):
var i = last row that you have modify: number;
worksheet.getRow(i).commit();
workbook.xlsx.writeFile('Veritas_Full_082819.xlsx').then(()=>{
}).catch((err)=>{
throw err;
});

recursively build a tree from an array javascript

From a .csv file I need to build a tree structure using three columns below.
Column state should be the parent node, id is a child node of state and ndi is a child of id node.
Currently my program can read the .csv file and store it in a two dimensional array.
Here is my code: Link to .csv file
<body>
<input type="file" id="files" name="files[]" multiple />
<output id="list"></output>
<script>
function handleFileSelect(evt) {
var files = evt.target.files;
for (var i = 0, f; f = files[i]; i++) {
var reader = new FileReader();
reader.onload = (function(theFile) {
return function(e) {
var string = e.target.result;
console.log(string);
var array1=string.split("\n");
alert(array1.length)
var array2 = new Array();
for(var i=0; i< array1.length; i++){
array2[i] = array1[i].split(",");
}
//completed upto saving as 2D array
};
})(f);
reader.readAsText(f);
}
}
document.getElementById('files').addEventListener('change', handleFileSelect, false);
</script>
I want to build a tree structure out of it.
This should do it, replace your second for with the code below:
// We cannot define our own keys for Javascript arrays, so we are using Object
var result = new Object();
var salesIndex = 8;
var idIndex = 0;
var ndiIndex = 7;
for(var i=0; i< array1.length; i++){
// array containing all line's columns
var columns = array1[i].split(",");
// especific columns that is of our interest
var rowSale = columns[salesIndex];
var rowId = columns[idIndex];
var rowNdi = columns[ndiIndex];
// If sale key doesn't exists in the array, add it
if (!(rowSale in columns)) {
result.rowSale.rowId = new Array();
result.rowSale.rowId.push(rowNdi);
} else if (!(rowId in columns.rowSale)) {
// If id key doesn't exists in the array, add it
result.rowSale.rowId = new Array();
result.rowSale.rowId.push(rowNdi);
} else if (!columns.rowSale.rowId.indexOf(rowNdi)) {
// If ndi isn't in the array, add it
result.rowSale.rowId.push(rowNdi);
}
}
If I did'nt missunderstand you, this should do the trick:
function buildTree(input) {
var output = {};
for (var i in input) {
var state = input[0];
var id = input[1];
var ndi = input[2];
if (output[state] === undefined) output[state] = {};
if (output[state][id] === undefined) output[state][id] = [];
output[state][id].push(ndi);
};
return output;
};

Javascript object become undefined on recordset

I have an acces database and I would like to import data to javascript.
This is my code:
function Flight(){
this.number;
this.day;
this.updateDate;
this.html;
}
var dbPath = "mypath\\flight_bdd.mdb";
var flights = [];
function executeRequest(request){
//get datas
var adoConn = new ActiveXObject("ADODB.Connection");
var adoCmd = new ActiveXObject("ADODB.Command");
adoConn.Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source='" + dbPath + "'");
adoCmd.ActiveConnection = adoConn;
var adOpenDynamic=2;
var adLockOptimistic=3;
var rs = new ActiveXObject("ADODB.Recordset");
rs.open(request, adoConn, adOpenDynamic, adLockOptimistic);
return rs;
}
function loadFlightsFromDatabase(){
//get datas
var rs = executeRequest("SELECT * FROM flight_data");
//empty flight array
flights = [];
//create flights
var i = 0
while(!rs.eof){
flights[i] = new Flight();
//set flight data
flights[i].number = rs.fields("flight_number");
console.log(flights[i].number);
rs.MoveNext();
console.log(flights[i].number);
i++;
}
}
The first console output returns the flight number and the second one returne undefined.
I think the value of the recordset is updated in my object when I have a move next, is there a way to prevent it ?
I think your connection goes out of scope and is getting closed. Try creating a disconnected recordset:
var adOpenStatic = 3;
var adUseClient = 3;
var adLockBatchOptimistic = 4;
var rs = new ActiveXObject("ADODB.Recordset");
rs.CursorLocation = adUseClient;
rs.open(request, adoConn, adOpenStatic, adLockBatchOptimistic);
rs.ActiveConnection = null;
adoConn.Close;
return rs;
But that said, rs.MoveNext(); should not affect already assigned property of your object (unless it's a reference type). What type is .number - can u show structure of Flight?
I find a solution,
I I concatenate my recordset
flights[i].number = rs.fields("flight_number") + "";
it works !!

Using YUI to read data from HTML table?

I generate an html table using YUI/JavaScript. I am now trying to go through and store the information that is generated by looking at each item in the table using a for loop.
var savedata = function(){
var tabledata = Y.one("#generatedtable")._node;
var jData = [];
for (var r in tabledata.rows){
var samplerow = {};
samplerow.timestamp = r.cells[0].innerHTML;
samplerow.volts = r.cells[1].innerHTML;
samplerow.amps = r.cells[2].innerHTML;
samplerow.kW = r.cells[3].innerHTML;
samplerow.kWh = r.cells[4].innerHTML;
samplerow.sessionid = r.cells[5].innerHTML;
jData.push(samplerow);
}
};
using Chrome developer tools I can see that Y.one("#generatedtable")._node.rows gives me an HTMLcollection of [X]. This signifies the number of rows that were created by my previous function. Row[0] is just headers and I want to skip over this row. The loop fails on the
samplerow.timestamp = r.cells[0].innerHTML;
line. How should I structure this for loop to go through rows[0] to [X] to store in my JSON Data variable?
var savedata = function(){
var tabledata = Y.one("#generatedtable")._node;
var jData = [];
var i = 1;
var length = tabledata.rows.length
while (i<length){
var samplerow = {};
var r = tabledata.rows[i];
samplerow.timestamp = r.cells[0].innerHTML;
samplerow.volts = r.cells[1].innerHTML;
samplerow.amps = r.cells[2].innerHTML;
samplerow.kW = r.cells[3].innerHTML;
samplerow.kWh = r.cells[4].innerHTML;
jData.push(samplerow);
i++;
}
alert(jData);
};

Categories