NodeJS checking if XML element exists and add or delete

68
January 19, 2021, at 6:10 PM

I'm working with XML in NodeJS. I've been using the xmlbuilder to create my XML. The problem is that now I need to check if a element already exists and delete or update it. For example, I have the following XML

<?xml version="1.0"?>
<listings>
    <listing>
        <id>1</id>
        <name>TEST</name>
        <description>TEST</description>
    </listing>
    <listing>
        <id>2</id>
        <name>TEST</name>
        <description>TEST</description>
    </listing>
</listings>

Then, I call my updateXML controller to add data to it.

const builder = require('xmlbuilder');
const fs = require('fs');
const path = require("path");
exports.updateXML = async (req, res, next) => {
    const data = req.body.data;
    /* 
        For example data is
        {
            id: 2,
            name: "Test2",
            description: "Desc2"
        }
    */
    const xmlFile = fs.readFileSync(path.resolve(__dirname, "./oodle.xml"), 'utf8');
    
    if(/*How do I check if the xmlFile has a <id> === data.id?*/) {
        // If id matches. How can I delete the whole <listing> node for that id?
    }
    const newListing = builder.create('listing');
    newListing.ele("id", data.id);
    newListing.ele("name", data.name);
    newListing.ele("description", data.description);
    // How can I add the newListing node to the xmlFile?
}

Thanks

Answer 1

I don't believe it's really necessary to remove the node with the duplicate <id>, create a new <listing> node and then insert it into the xml. At least as far as the sample xml in your question is concerned, you can just modify the text child nodes of the relevant <listing> node.

Something along the lines of:

const { select } = require('xpath');
let query = `//listing[./id[./text()="${data.id}"]]`;
const nodes = select(query, doc.node);
 nodes.forEach(function (node) {
    nam = select('.//name/text()',node)
    desc = select('.//description/text()',node)
    nam[0].data = data.name;
    desc[0].data = data.description;
  });
 const serializedXML = doc.end({ format: 'xml', prettyPrint: true });
 console.log(serializedXML)

Output:

<?xml version="1.0"?>
<listings>
  <listing>
    <id>1</id>
    <name>TEST</name>
    <description>TEST</description>
  </listing>
  <listing>
    <id>2</id>
    <name>Test2</name>
    <description>Desc2</description>
  </listing>
</listings>
READ ALSO
Extracting array value from nested array of objects

Extracting array value from nested array of objects

Hi guys i have created the following array of objectsAnd to be honest i am a little bit lost

106
How to use CloudFireStore on Android Stuido

How to use CloudFireStore on Android Stuido

I want to use CloudFireStore From Firebase How can I start It on Android Studio Project

81
Trouble Hosting Angular/Core App - Failed to load module script: The server responded with a non-Javascript MIME type

Trouble Hosting Angular/Core App - Failed to load module script: The server responded with a non-Javascript MIME type

I have been trying to figure this out for a while nowWhenever I'm trying to host the simple Angular hello world app with Dotnet core, my browser is struggling with the MIME types of the javascript modules and the CSS

137
Getting a &ldquo;Cannot GET /page_name&rdquo; in my Node.js Heroku app

Getting a “Cannot GET /page_name” in my Node.js Heroku app

I have successfully pushed my Nodejs application to Heroku and I can access the website through the url: gatorcode

97