views:

1776

answers:

1

I need to take an existing xml file, and modify just a few attributes and write the file back out.

I was thinking of using libxml2 to get this done. Application is C/C++ running on Linux.

Thing is, libxml2 seems to include several variations of the kitchen sink, along with portable washrooms, showers, and various other things connected via the same plumbing. There are different parsers available, and different ways of doing things. For someone who hasn't used libxml2 before, this is a bit intimidating.

What example should I be looking at, so that in the end, my output .xml is identical to the original input file, plus the changes I've made? So far, I've been playing with libxml2's tree1.c, tree2.c, and reader1.c examples, but with just these the output xml wont be anywhere near the same.

+8  A: 
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
#include <libxml/xpath.h>

//Load in the xml file from disk
xmlDocPtr pDoc = xmlParseFile("file.xml");
//Or from a string xmlDocPtr pDoc = xmlNewDoc("<root><element/></root>");

//Do something with the document
//....

//Save the document back out to disk.
xmlSaveFileEnc("file.xml", pDoc, "UTF-8");

The main things you want are probably these functions:

xmlNodePtr pNode = xmlNewNode(0, (xmlChar*)"newNodeName");
xmlNodeSetContent(pNode, (xmlChar*)"content");
xmlAddChild(pParentNode, pNode);
xmlDocSetRootElement(pDoc, pParentNode);

And here is a quick example of using xpath to select things:

//Select all the user nodes
xmlChar *pExpression((xmlChar*)_T("/users/user"));
xmlXPathObjectPtr pResultingXPathObject(getnodeset(pDoc, pExpression));
if (pResultingXPathObject)
{
 xmlNodeSetPtr pNodeSet(pResultingXPathObject->nodesetval);
 for(int i = 0; i < pNodeSet->nodeNr; ++i) 
 {
  xmlNodePtr pUserNode(pNodeSet->nodeTab[i]);
                   //do something with the node
 }
}
xmlXPathFreeObject(pResultingXPathObject);
Brian R. Bondy