Delete an XML Node using libxml2 in C

In the previous article we saw how to add a new XML node. Here we’ll see how to delete an an XML node from a file. We’ll use the same example XML file.

<?xml version="1.0"?>
<catalog>
   <book id="bk101">
      <author>Gambardella, Matthew</author>
      <title>XML Developer's Guide</title>
      <genre>Computer</genre>
      <price>44.95</price>
      <publish_date>2000-10-01</publish_date>
      <description>An in-depth look at creating applications
      with XML.</description>
   </book>
   <book id="bk102">
      <author>Ralls, Kim</author>
      <title>Midnight Rain</title>
      <genre>Fantasy</genre>
      <price>5.95</price>
      <publish_date>2000-12-16</publish_date>
      <description>A former architect battles corporate zombies,
      an evil sorceress, and her own childhood to become queen
      of the world.</description>
   </book>
   <book id="bk103">
      <author>Corets, Eva</author>
      <title>Maeve Ascendant</title>
      <genre>Fantasy</genre>
      <price>5.95</price>
      <publish_date>2000-11-17</publish_date>
      <description>After the collapse of a nanotechnology
      society in England, the young survivors lay the
      foundation for a new society.</description>
   </book>
</catalog>

In this example, we have 3 ‘book‘ nodes under ‘catalog‘. We’ll write a C program to delete one of them.

Program to Delete XML Node

#include <stdio.h>
#include <libxml/parser.h>

/*gcc `xml2-config --cflags --libs` test.c*/

xmlNode * find_node(xmlNode * node, char * book_id) {
  
  xmlNode * result;
  
  if (node == NULL) return NULL;
  
  while(node) {
    if((node->type == XML_ELEMENT_NODE) 
        && (strcmp(node->name, "book") == 0)
        && (strcmp(xmlGetProp(node, "id"), book_id) == 0)) {
      return node;
    }
    
    if (result = find_node(node->children, book_id)) return result;
    
    node = node->next;
  }
  
  return NULL;
}

void delete_node(xmlNode *root, char* book_id) {
  xmlNode* node = find_node(root, book_id);
  
  if(node == NULL) {
    printf("Book with id %s not found\n", book_id);
    return;
  }
  
  xmlUnlinkNode(node);
  xmlFreeNode(node);
}

void save_to_file(xmlDoc *doc, char *file_name) {
  xmlChar *xmlbuff;
  int buffersize;
  FILE *fp;
  
  xmlDocDumpFormatMemory(doc, &xmlbuff, &buffersize, 1);
  
  fp = fopen(file_name, "w+");
  fprintf(fp, xmlbuff);
  fclose(fp);
}

int main(){
  xmlDoc *doc = NULL;
  xmlNode *root_element = NULL;

  doc = xmlReadFile("input.xml", NULL, 0);

  if (doc == NULL) {
    printf("Could not parse the XML file.\n");
    return 1;
  }

  root_element = xmlDocGetRootElement(doc);

  delete_node(root_element, "bk102");
  
  save_to_file(doc, "output.xml");
  
  xmlFreeDoc(doc);

  xmlCleanupParser();
  
  return 0;
}

This program has the following important functions.

find_node(): It finds a ‘book‘ node based on a book id. It traverses the XML doc and returns a node whose node name is ‘book‘ and the ‘id‘ property of that node is equal to the input book id.

delete_node(): It takes a book id as input and deletes the book node with this book id. It first finds the node by calling the find_node() function. Then it detaches that node from the XML doc by calling xmlUnlinkNode() function. After that it frees the detached node using xmlFreeNode() to void memory leak.

save_to_file(): Saves the XML doc into a file.

In the main() function, we first read the “input.xml” file. So this ‘input.xml‘ files needs to be present in time of running the program in the same directory. Then we called the delete_node() function to delete the second book entry. That’s why we passed ‘bk102book id as input. After deleting the node, we saved the XML content to ‘output.xml‘ file.

To compile this program, run this command.

gcc `xml2-config --cflags --libs` test.c -o test

It requires libxml2 development package. If it is not already installed, then you can follow this article to install that first.

If you run this program (./test), the ‘output.txt‘ will get generated in the same directory. The ‘output.txt‘ will not have the second book entry.

Delete an xml node output

Author: Srikanta

I write here to help the readers learn and understand computer programing, algorithms, networking, OS concepts etc. in a simple way. I have 20 years of working experience in computer networking and industrial automation.


If you also want to contribute, click here.

One thought on “Delete an XML Node using libxml2 in C”

  1. the instructions
    xmlUnlinkNode(node);
    xmlFreeNode(node);

    leave a blank line in the output file, is there a way to avoid that or to clean the blank line

Leave a Reply

Your email address will not be published. Required fields are marked *

0
0
0
0
0
0