Posts tagged ‘XML’

Programming with XML in Firefox Add-ons

The eHow Earnings Tracker stores its data in XML format, so one of the things that I needed to learn how to do was program with XML in Firefox Add-ons.  Mozilla has a whole section of code snippets dedicated to XML but I will walk through exactly what I did in the development of the tracker and point out some gotchas that I figured out along the way.

The first step in this process was to figure out how to create an XML DOM tree in memory.  This turned out to be pretty straightforward to do thanks to Mozilla’s How to create a DOM tree documentation.  I wound up with the following code to create my basic XML DOM hierarchy:

var createEarningsDOM = function()
{
    m_trackerDOM = document.implementation.createDocument(null, null, null);

    var trackerNode = m_trackerDOM.createElement(m_xmlNodeTracker);
    trackerNode.setAttribute(m_xmlAttrVersion, m_xmlVersion);

    m_articleListElem = m_trackerDOM.createElement(m_xmlNodeArticleList);
    trackerNode.appendChild(m_articleListElem);

    m_statsElem = m_trackerDOM.createElement(m_xmlNodeStats);
    trackerNode.appendChild(m_statsElem);

    m_trackerDOM.appendChild(trackerNode);
};

You should notice a couple of things about the source code above.  First, I create variables to hold my node and attribute names.  This ensures consistency when I refer to particular nodes and attributes throughout my code.  It also means that if I decide to change the string for a node or attribute name, I only need to do it in one spot.  The second thing is that I create variables to hold references to DOM nodes so that I can easily manipulate them later in the code.

Now that I was able to create an XML DOM tree in memory, it was time to figure out how to write it out to a file.  Mozilla has some decent documentation on parsing and serializing XML.  I combined the information there with what I learned about file I/O and wrote the following code to serialize my XML DOM to a file:

var s = new XMLSerializer();
XML.prettyIndent = 4;
var xmlString = XML(s.serializeToString(m_trackerDOM)).toXMLString();

if(!FileIO.write(m_earningsFile, xmlString))
{
    throw Error("Failed to save file " + m_earningsFile.path);
}

The “pretty” serialization for XML strings is really cool because it formats the XML so that it’s very readable.  It makes life a lot easier when you need to look at the contents the XML file.

Now that I was able to write out XML to a file, I needed a way to read it back in again later.  I used the DOMParser.  The one thing to watch out for with the DOMParser is that when the parsing fails, it doesn’t throw an exception.  Instead, it returns an XML document that contains the parsing error.

This is the code I came up with for loading the XML DOM from a file:

var fileContents = FileIO.read(currentFile);

if(fileContents)
{
    logMessage("\tParsing file");
    var parser = new DOMParser();
    m_trackerDOM = parser.parseFromString(fileContents, "text/xml");

    logMessage("\tLooking for " + m_xmlNodeArticleList);
    m_articleListElem = m_trackerDOM.getElementsByTagName(m_xmlNodeArticleList)[0];

    if(!m_articleListElem)
    {
        // XML parsing failed, grab error
        var s = new XMLSerializer();
        XML.prettyIndent = 4;
        logMessage(XML(s.serializeToString(m_trackerDOM)).toXMLString());                    
        throw Error("Failed to parse XML data file");
    }
}

In this piece of code, I read in the file contents and parse it, attempting to find the DOM element that I’m looking for.  If I don’t find the element then something has gone wrong – either the parsing failed, or the XML is not what I’m expecting it to be.  In either case, I log the results of the parseFromString() function to my log file so that I know what went wrong.