In the previous article, we saw how to parse an XML file. Here we’ll see how to add new node to XML file using C programming language. Here also we’ll use libxml2 parser.
We’ll use this XML file as an example.
<?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>
Here we have 3 book nodes under the catalog node. We’ll add one more book node.
C Program to Add New Node to XML File
#include <stdio.h>
#include <libxml/parser.h>
/*gcc `xml2-config --cflags --libs` test.c*/
xmlNode * find_node(xmlNode * node, char * name) {
xmlNode * result;
if (node == NULL) return NULL;
while(node) {
if((node->type == XML_ELEMENT_NODE) && (strcmp(node->name, name) == 0)) {
return node;
}
if(result = find_node(node->children, name)) return result;
node = node->next;
}
return NULL;
}
void add_node(xmlNode *root, char* id, char* author, char* title) {
xmlNode* node = find_node(root, "catalog");
xmlNode* new_node = NULL;
xmlNode* new_child_node = NULL;
if(node == NULL) return;
new_node = xmlNewNode(NULL, BAD_CAST "book");
xmlSetProp(new_node, "id", id);
new_child_node = xmlNewNode(NULL, BAD_CAST "author");
xmlNodeSetContent(new_child_node, author);
xmlAddChild(new_node, new_child_node);
new_child_node = xmlNewNode(NULL, BAD_CAST "title");
xmlNodeSetContent(new_child_node, title);
xmlAddChild(new_node, new_child_node);
xmlAddChild(node, new_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);
add_node(root_element, "bk500", "F. Scott Fitzgerald", "The Great Gatsby");
save_to_file(doc, "output.xml");
xmlFreeDoc(doc);
xmlCleanupParser();
return 0;
}
This program reads the “input.xml” file and adds a new book node. Then it saves the content to “output.xml“. We could overwrite the “input.xml” also. Lets have a look at the various functions of this program.
find_node(): It can find any node in the XML file based on a node name. If found, then it returns the node pointer. We used this function to find the ‘catalog‘ node.
add_node(): This function adds new book node under ‘catalog‘. It first finds the ‘catalog‘ node by calling find_node() function. Then it creates the ‘book‘ and adds the ‘id‘ property. This shows how to add a property of attribute to an XML node. The two child nodes, ‘ author‘ and ‘title‘, are created and added to the ‘book‘ node. We set content to ‘author‘ and ‘title‘ nodes. Finally the ‘book‘ node is added under ‘catalog‘.
save_to_file(): This function saves the XML content to a file.
The main() function first reads the ‘input.xml‘ file and calls the add_node() function with required information to add a ‘book‘ node. Then it calls the save_to_file() function to save the modified XML content to ‘output.xml‘ file.
If you don’t have libxml2 development library installed on your system, then you have to install that first to compile the program.
To compile this program, run this command.
gcc `xml2-config --cflags --libs` test.c -o test
The ‘input.xml‘ file needs to be present in the same directory in time of running the program.
The ‘output.xml’ file would be generated in the same directory. If we open the file, we can see the new book entry..