KingsLight
KingsLight

Reputation: 31

Reading xml attribute value using node js

i am trying to read an attribute value from xml using nodejs code snippet and below is my xml Data. Trying to fetch environment QA or UAT. I wrote the code to parse the xml. Now the challenge is not able to understand this output format of console.log. Not sure which API have to be used get/read "name" attribute value.

Please help me to read the value of name attribute.

<?xml version="1.0" encoding="UTF-8"?>
<testsuites>
<testsuite name="QA" ></testsuite>
<testcase status="success>"></testcase>
<testsuite name="QA2" ></testsuite>
<testcase status="success>"></testcase>
<testsuite name="UAT" ></testsuite>
<testcase status="success>"></testcase>
<testsuite name="UAT2" ></testsuite>
<testcase status="success>"></testcase>
<testsuite name="SandBox" ></testsuite>
<testcase status="success>"></testcase>
<testsuite name="SandBox" ></testsuite>
</testsuites>

`

const fs = require("fs");
const path = require("path")
const xml2js = require("xml2js")

let files;
let htmlobj = '<h3>Summary</h3><table><tr><th>Error Count</th></tr>'
files = fs.readdirSync(__dirname);
var parser = new xml2js.Parser();
let filecount = 0;
let counter = 0;
const junitfiles = {};
files.forEach(file => {
            if (path.extname(file) != ".xml") return;
                const extname = path.extname(file);
                const filename = path.basename(file, extname);
                const obsolutePath = path.resolve(__dirname, file); 
                fs.readFile(obsolutePath, function(err, data) {
                        if (err) {
                            console.log('error in readFile', err);
                        } else {
                            parser.parseString(data, function(err, result) {
                                if (err) {
                                    console.log('error parsing', err)
                                }
                             else {
                                let resultvalue = 0;
                                let envcount = 0;
                                for (var i = 0; i < result.testsuites.testsuite.length; i++) {
                                    resultvalue = result.testsuites.testsuite[i];
                                    console.log('value of testsuite object', resultvalue);
                                }
                            }
                        });
                        }
                });
});

`

Output of Node js code

value of testsuite object { '$': { name: 'QA' } }
value of testsuite object { '$': { name: 'QA2' } }
value of testsuite object { '$': { name: 'UAT' } }
value of testsuite object { '$': { name: 'UAT2' } }
value of testsuite object { '$': { name: 'SandBox' } }
value of testsuite object { '$': { name: 'SandBox' } }

Upvotes: 1

Views: 1917

Answers (2)

Tuan Anh Tran
Tuan Anh Tran

Reputation: 7237

this is a simpler way to access testsuite name with camaro

const { transform } = require('camaro')

async function main() {
    const xml = `
    <?xml version="1.0" encoding="UTF-8"?>
<testsuites>
<testsuite name="QA" ></testsuite>
<testcase status="success>"></testcase>
<testsuite name="QA2" ></testsuite>
<testcase status="success>"></testcase>
<testsuite name="UAT" ></testsuite>
<testcase status="success>"></testcase>
<testsuite name="UAT2" ></testsuite>
<testcase status="success>"></testcase>
<testsuite name="SandBox" ></testsuite>
<testcase status="success>"></testcase>
<testsuite name="SandBox" ></testsuite>
</testsuites>
`

    template = {
        names: ['testsuites/testsuite', '@name']
    }
    const { names } = await transform(xml, template)
    console.log(names);
}

main()

output

[ 'QA', 'QA2', 'UAT', 'UAT2', 'SandBox', 'SandBox' ]

Upvotes: 0

Bergur
Bergur

Reputation: 4057

To answer your question:

Add below console.log('value of testsuite object', resultvalue);

const attributeName = resultvalue.$.name
console.log('value of attribute name is ', attributeName)

On another note: Be carefull with .forEach and callbacks, you're not gonna get the information in the correct order, since its async code.

The order you think your code is running

  1. Go through files
  2. Loop through file nr 1
  3. Read file nr 1
  4. Console log contensts of file nr 1
  5. Loop through file nr 2 ..etc, etc.

But callbacks are like the name suggest "call me back, when you're ready" - so its not gonna console log anything until it has read the file. Meanwhile the loop still continues, so you could have something like

  1. Go through files
  2. Loop through file nr 1
  3. Read file nr 1
  4. Loop through file nr 2
  5. Console log contensts of file nr 1 ..etc, etc.

see how items 4 og 5 switched.

Upvotes: 1

Related Questions