Parsing xml using Node

Hey gcat, hope you're fine. How did you manage to have your buttons work ?

hey @Sylvain
still have a cold and feel tired but ok.

i have this at the top of my custom module:

/*********** GENERATING EXPRESSION MAPS DYNAMCALLY - YESSSSS!!!!!! ************/

const path = nativeRequire('path');
const fs = nativeRequire('fs');
const xml2js = nativeRequire('xml2js');
const glob = nativeRequire('glob');
const mapFiles = glob.sync(path.join(__dirname, '../../Steinberg/Expression Maps/*.expressionmap'));
const trackID = '' // still has to be put manually

async function buildMap() {

     artArr = [];
     artColor = [];
    for (const mapFile of mapFiles) {
        if (mapFile.includes(trackID)) {
            const parser = new xml2js.Parser({
                explicitArray: false,
                mergeAttrs: true
            }); // 'mergeAttrs: true' was essential

            console.log('Selected Map:  ' + mapFile);

            const data = await fs.promises.readFile(mapFile);
            const result = await parser.parseStringPromise(data);
            const art = result.InstrumentMap.member[1].list.obj;
            for (let i = 0, len = art.length; i < len; i++) {
                console.log('Articulation at position: ' + i + '  ' + art[i].member[1].string.value + '; ' +
                    'Color Value: ' + art[i].int.value) // articulatins and color value
                artArr[i] = art[i].member[1].string.value
                artColor[i] = art[i].int.value
            }
            // once we've run this inner for loop once, we can't
            // run it again because it will overwrite values in 
            // artArr and artColor, so we break the outer for loop
            break;
        }
    }
    return { artArr, artColor };
}

buildMap().then(result => {
    // use your results here
    console.log(artArr, artColor);
}).catch(err => {
    console.log(err);
});

the trackID has still to be put manually because i wanna use trackname to get the ID but trackname is generated after buildMap(). i just don't know how to get this part of the code.

i use artArr to call the buttons:

buttonGrid = artArr.length;
            labelTexts = Object.values(artArr);
            for (i = 0; i < buttonGrid; i++)
                {
                var label = labelTexts[i]
                receive({address: Object.values(buttons)[i], args: [{type: 'i', value: 1}]})
                receive({address: Object.values(labels)[i], args: [{type: 's', value: label}]})
                }
                                
            for (i = buttonGrid; i < 55; i++)
                {
                receive({address: Object.values(buttons)[i], args: [{type: 'i', value: 0}]})                 
                }
            return
            
        } 

Thank you, that's what i was trying to set... will have a look at it soon. For now, i'm in a machine-to-human-translation's mood... just to get all clear in my head, about what's going on in these codes, line by line... their meaning, their structure... :crazy_face:
Had some trouble with Protokol app (which kind of stole my hui connection...), and with my Big Cubase Template... lost all my expression maps settings (not the expression maps themselves, but i have to "recharge" every single e.m. for each track... :partying_face:)

:grimacing: :grimacing: :grimacing:

happy "recharging" then... :crazy_face:

You need to trigger the update of your labels and then run the function.
For example (none of the below is checked as working code but to give the idea:


const myTrigger = true

if (mytrigger) {
/*********** GENERATING EXPRESSION MAPS DYNAMCALLY - YESSSSS!!!!!! ************/

const path = nativeRequire('path');
const fs = nativeRequire('fs');
const xml2js = nativeRequire('xml2js');
const glob = nativeRequire('glob');
const mapFiles = glob.sync(path.join(__dirname, '../../Steinberg/Expression Maps/*.expressionmap'));
const trackID = '' // still has to be put manually

async function buildMap() {

     artArr = [];
     artColor = [];
    for (const mapFile of mapFiles) {
        if (mapFile.includes(trackID)) {
            const parser = new xml2js.Parser({
                explicitArray: false,
                mergeAttrs: true
            }); // 'mergeAttrs: true' was essential

            console.log('Selected Map:  ' + mapFile);

            const data = await fs.promises.readFile(mapFile);
            const result = await parser.parseStringPromise(data);
            const art = result.InstrumentMap.member[1].list.obj;
            for (let i = 0, len = art.length; i < len; i++) {
                console.log('Articulation at position: ' + i + '  ' + art[i].member[1].string.value + '; ' +
                    'Color Value: ' + art[i].int.value) // articulatins and color value
                artArr[i] = art[i].member[1].string.value
                artColor[i] = art[i].int.value
            }
            // once we've run this inner for loop once, we can't
            // run it again because it will overwrite values in 
            // artArr and artColor, so we break the outer for loop
            break;
        }
    }
    return { artArr, artColor };
}

buildMap().then(result => {
    // use your results here
buttonGrid = artArr.length;
            labelTexts = Object.values(artArr);
            for (i = 0; i < buttonGrid; i++)
                {
                var label = labelTexts[i]
                receive({address: Object.values(buttons)[i], args: [{type: 'i', value: 1}]})
                receive({address: Object.values(labels)[i], args: [{type: 's', value: label}]})
                }
                                
            for (i = buttonGrid; i < 55; i++)
                {
                receive({address: Object.values(buttons)[i], args: [{type: 'i', value: 0}]})                 
                }
            return
            
        }
}).catch(err => {
    console.log(err);
});

}
1 Like