javascriptnode.jsxmlxml2js

Selecting xml node by attribute id


My aim is simple, I just need to get the value by an attrbiute. For example consider this xml:

<?xml version="1.0" encoding="UTF-8"?>
<preferences>
    <custom-preferences>
        <staging>
             <preference preference-id="foo">true</preference>
             <preference preference-id="bar">true</preference>
        </staging>
    <custom-preferences>
<preferences>
</xml>

The xml is in a file, this is what I have so far:

var fs = require('fs'),
xml2js = require('xml2js');
 
var parser = new xml2js.Parser();
fs.readFile(pref, function(err, data) {parser.parseString(data, function (err, result) {

    console.log(result.preferences['custom-preferences'][0].staging[0].preference[0]);

    });
});

So if I hard code the index it will work, but can I select the node where preference-id = foo or bar etc.

I'm trying to avoid reading the parent node and performing a for each. I am happy and willing to use other package or libraries if it will help me to achieve the goal.


Solution

  • It is possible by jsdom or xml.etree.ElementTree

    Code by node.js

    const jsdom = require("jsdom");
    
    const response = `
    <?xml version="1.0" encoding="UTF-8"?>
    <preferences>
        <custom-preferences>
            <staging>
                 <preference preference-id="foo">true</preference>
                 <preference preference-id="bar">true</preference>
            </staging>
        </custom-preferences>
    </preferences>`
    
    const dom = new jsdom.JSDOM(response);
    console.log('foo: '   + dom.window.document.querySelector('[preference-id="foo"]').textContent)
    console.log('bar: '   + dom.window.document.querySelector('[preference-id="bar"]').textContent)
    

    Result

    $ node find-attribute.js
    foo: true
    bar: true
    

    Code by Python

    import xml.etree.ElementTree as ET
    document = """\
    <?xml version="1.0" encoding="UTF-8"?>
    <preferences>
        <custom-preferences>
            <staging>
                 <preference preference-id="foo">true</preference>
                 <preference preference-id="bar">true</preference>
            </staging>
        </custom-preferences>
    </preferences>
    """
    
    root = ET.fromstring(document)
    print("preference-id='foo' " + root.find(".//*[@preference-id='foo']").text)
    print("preference-id='bar' " + root.find(".//*[@preference-id='bar']").text)
    

    Result

    $ python find-attribute.py
    preference-id='foo' true
    preference-id='bar' true