<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>learning python &#187; xml</title>
	<atom:link href="http://www.learningpython.com/category/python/xml/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.learningpython.com</link>
	<description>one man's journey into python...</description>
	<lastBuildDate>Mon, 26 Apr 2010 01:21:51 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=abc</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Elegant XML parsing using the ElementTree Module</title>
		<link>http://www.learningpython.com/2008/05/07/elegant-xml-parsing-using-the-elementtree-module/</link>
		<comments>http://www.learningpython.com/2008/05/07/elegant-xml-parsing-using-the-elementtree-module/#comments</comments>
		<pubDate>Wed, 07 May 2008 16:21:48 +0000</pubDate>
		<dc:creator>selsine</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[xml]]></category>
		<category><![CDATA[ElementTree]]></category>

		<guid isPermaLink="false">http://www.learningpython.com/?p=74</guid>
		<description><![CDATA[
			
				
			
		
Mark Mruss
Note: This article was first published the October 2007 issue of Python Magazine
XML is everywhere.  It seems you can&#8217;t do much these days unless you utilize XML in one way or another. Fortunately, Python developers have a new tool in our standard arsenal: the ElementTree module. This article aims to introduce you to [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.learningpython.com%2F2008%2F05%2F07%2Felegant-xml-parsing-using-the-elementtree-module%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.learningpython.com%2F2008%2F05%2F07%2Felegant-xml-parsing-using-the-elementtree-module%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p><strong>Mark Mruss</strong></p>
<p><strong>Note:</strong> This article was first published the October 2007 issue of <a href="http://www.pythonmagazine.com">Python Magazine</a></p>
<p>XML is everywhere.  It seems you can&#8217;t do much these days unless you utilize XML in one way or another. Fortunately, Python developers have a new tool in our standard arsenal: the ElementTree module. This article aims to introduce you to reading, writing, saving, and loading XML using the ElementTree module.</p>
<ol>
<li><a href="#Introduction">Introduction</a></li>
<li><a href="#ReadingXMLdata">Reading XML data</a></li>
<li><a href="#Listing1">Listing 1</a></li>
<li><a href="#Listing2">Listing 2</a></li>
<li><a href="#ReadingXMLAttributes">Reading XML Attributes</a></li>
<li><a href="#WritingXML">Writing XML</a></li>
<li><a href="#Listing3">Listing 3</a></li>
<li><a href="#WritingXMLAttributes">Writing XML Attributes</a></li>
<li><a href="#ReadingXMLFiles">Reading XML Files</a></li>
<li><a href="#WritingXMLDatatoaFile">Writing XML Data to a File</a></li>
<li><a href="#ReadingfromtheWeb">Reading from the Web</a></li>
<li><a href="#Conclusion">Conclusion</a></li>
</ol>
<p><span id="more-74"></span><!--more--></p>
<h2><a href="#Introduction">Introduction</a></h2>
<p>It seems like everyone needs to parse XML these days.  They&#8217;re either saving their own information in XML or loading in someone else&#8217;s data.  This is why I was glad to learn that as of Python 2.5, the <em>ElementTree</em> XML package has been added to the standard library in the XML module.</p>
<p>What I like about the <em>ElementTree</em> module is that it just seems to make sense.  This might seem like a strange thing to say about an XML module, but I&#8217;ve had to parse enough XML in my time to know that if an XML module makes sense the first time you use it, it&#8217;s probably a keeper. The <em>ElementTree</em> module allows me to work with XML data in a way that is similar to how I <em>think</em> about XML data.</p>
<p>A subset of the full <em>ElementTree</em> module is available in the Python 2.5 standard library as <code>xml.etree</code>, but you don&#8217;t have to use Python 2.5 in order to use the <em>ElementTree</em> module. If you are still using an older version of Python (1.5.2 or later) you can simply download the module from its website and manually install it on your system.  The website also has very easy to follow installation instructions, which you should consult to avoid issues while installing <em>ElementTree</em>.</p>
<p>In general, the <em>ElementTree</em> module treats XML data as a list of lists.  All XML has a root element that will have zero or more subelements (or child elements). Each of those subelements may in turn have subelements of their own.  The best way to think about this is with a brief example.</p>
<p>First let&#8217;s take a look at some sample XML data:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-default">&lt;</span><span class="hl-identifier">root</span><span class="hl-default">&gt;
&lt;</span><span class="hl-identifier">child</span><span class="hl-default">&gt;</span><span class="hl-identifier">One</span><span class="hl-default">&lt;/</span><span class="hl-identifier">child</span><span class="hl-default">&gt;
&lt;</span><span class="hl-identifier">child</span><span class="hl-default">&gt;</span><span class="hl-identifier">Two</span><span class="hl-default">&lt;/</span><span class="hl-identifier">child</span><span class="hl-default">&gt;
&lt;/</span><span class="hl-identifier">root</span><span class="hl-default">&gt;</span></pre></div></div>
<p>Here we have a root element with two child elements. Each child element has some text associated with it seen here as &#8220;one&#8221; and &#8220;two&#8221;. If we examine the XML as a hierarchical list of lists we see that we have one element &#8220;root&#8221; in our root list.  Within the &#8220;root&#8221; element we have a list containing two subelements &#8220;child&#8221; and &#8220;child&#8221;. The two &#8220;child&#8221; elements would then contain empty lists representing their lack of subelements. Not too complicated so far, is it?</p>
<h2><a href="#ReadingXMLdata">Reading XML data</a></h2>
<p>Now let&#8217;s use the <em>ElementTree</em> package to parse this XML and print the text data associated with each child element.  To start, we&#8217;ll create a Python file with the contents shown in Listing 1.</p>
<p><strong><a href="#Listing1">Listing 1</a></strong></p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-comment">#!/usr/bin/env python

</span><span class="hl-reserved">def </span><span class="hl-identifier">main</span><span class="hl-brackets">()</span><span class="hl-default">:
	</span><span class="hl-reserved">pass

if </span><span class="hl-identifier">__name__</span><span class="hl-default"> == </span><span class="hl-quotes">&quot;</span><span class="hl-string">__main__</span><span class="hl-quotes">&quot;</span><span class="hl-default">:
	</span><span class="hl-identifier">main</span><span class="hl-brackets">()</span></pre></div></div>
<p>This is basically a template that I use for many of my simple &#8220;*.py&#8221; files.  It doesn&#8217;t actually do anything except set up the script so that when the file is run, the <code>main</code> method will be executed. Some people like to use the Python interactive interpreter for simple hacking like this. Personally, I prefer having my code stored in a handy file so I can make simple changes and re-run the entire script when I am just playing around.</p>
<p>The first thing that we need to do in our Python code is import the <em>ElementTree</em> module:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-reserved">from </span><span class="hl-identifier">xml</span><span class="hl-default">.</span><span class="hl-identifier">etree </span><span class="hl-reserved">import </span><span class="hl-identifier">ElementTree as ET</span></pre></div></div>
<p><strong>Note</strong>: If you are not using Python 2.5 and have installed the <em>ElementTree</em> module on your own, you should import the <em>ElementTree</em> module as follows:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-reserved">from </span><span class="hl-identifier">elementtree </span><span class="hl-reserved">import </span><span class="hl-identifier">ElementTree as ET</span></pre></div></div>
<p>This will import the ElementTree section of the module into your program aliased as ET.  However, you don&#8217;t have to import <em>ElementTree</em> using an alias; you can simply import it and access it as <code>ElementTree</code>. Using ET is demonstrated in the Python 2.5 &#8220;What&#8217;s new&#8221; documentation[1] and I think it&#8217;s a great way to eliminate some key strokes.</p>
<p>Now we&#8217;ll begin writing code in the <code>main</code> method.  The first step is to load the XML data described above.  Normally you will be working with a file or URL; for now we want to keep this simple and load the XML data directly from the text:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">element</span><span class="hl-default"> = </span><span class="hl-identifier">ET</span><span class="hl-default">.</span><span class="hl-identifier">XML</span><span class="hl-brackets">(
       </span><span class="hl-quotes">&quot;</span><span class="hl-string">&lt;root&gt;&lt;child&gt;One&lt;/child&gt;&lt;child&gt;Two&lt;/child&gt;&lt;/root&gt;</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span></pre></div></div>
<p>The <code>XML</code> function is described in the <em>ElementTree</em> documentation as follows: &#8220;Parses an XML document from a string constant. This function can be used to embed &#8220;XML literals&#8221; in Python code&#8221;[2].</p>
<p>Be careful here! The <code>XML</code> function returns an Element object, and not an ElementTree object as one might expect. Element objects are used to represent XML elements, whereas the ElementTree object is used to represent the entire XML document. Element objects <em>may</em> represent the entire XML document if they are the root element but will not if they are a subelement. ElementTree objects also add &#8220;some extra support for serialization to and from standard XML.&#8221;[3] The Element object that is returned represents the <code><root></root></code> element in our XML data.</p>
<p>Thankfully, the Element object is an iterator object so we can use a <code>for</code> loop to loop through all of its child elements:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-reserved">for </span><span class="hl-identifier">subelement </span><span class="hl-reserved">in </span><span class="hl-identifier">element</span><span class="hl-default">:</span></pre></div></div>
<p>This will give us all the child elements in the root element.  As mentioned earlier, each element in the XML tree is represented as an Element object, so as we iterate through the root element&#8217;s child elements we are getting Element objects with which to work. Meaning that each loop though the for loop will give us the next child element in the form of an Element object until there are no more children left. In order to print out the text associated with an Element object we simply have to access the Element object&#8217;s <code>text</code> attribute:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">for </span><span class="hl-identifier">subelement </span><span class="hl-reserved">in </span><span class="hl-identifier">element</span><span class="hl-default">:
       </span><span class="hl-reserved">print </span><span class="hl-identifier">subelement</span><span class="hl-default">.</span><span class="hl-identifier">text</span></pre></div></div>
<p>To recap, have a look at the code in Listing 2.</p>
<p><strong><a href="#Listing2">Listing 2</a></strong></p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-comment">#!/usr/bin/env python

</span><span class="hl-reserved">from </span><span class="hl-identifier">xml</span><span class="hl-default">.</span><span class="hl-identifier">etree </span><span class="hl-reserved">import </span><span class="hl-identifier">ElementTree as ET

</span><span class="hl-reserved">def </span><span class="hl-identifier">main</span><span class="hl-brackets">()</span><span class="hl-default">:
	</span><span class="hl-identifier">element</span><span class="hl-default"> = </span><span class="hl-identifier">ET</span><span class="hl-default">.</span><span class="hl-identifier">XML</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">&lt;root&gt;&lt;child&gt;One&lt;/child&gt;&lt;child&gt;Two&lt;/child&gt;&lt;/root&gt;</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
	</span><span class="hl-reserved">for </span><span class="hl-identifier">subelement </span><span class="hl-reserved">in </span><span class="hl-identifier">element</span><span class="hl-default">:
		</span><span class="hl-reserved">print </span><span class="hl-identifier">subelement</span><span class="hl-default">.</span><span class="hl-identifier">text

</span><span class="hl-reserved">if </span><span class="hl-identifier">__name__</span><span class="hl-default"> == </span><span class="hl-quotes">&quot;</span><span class="hl-string">__main__</span><span class="hl-quotes">&quot;</span><span class="hl-default">:
	</span><span class="hl-comment"># Someone is launching this directly
	</span><span class="hl-identifier">main</span><span class="hl-brackets">()</span></pre></div></div>
<p>Once you run the code you should get the following output:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">One
Two</span></pre></div></div>
<p>If an XML element does not have any text associated with it, like our root element, the Element object&#8217;s <code>text</code> attribute will be set to <code>None</code>. If you want to check if an element had any text associated with it, you can do the following:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">if </span><span class="hl-identifier">element</span><span class="hl-default">.</span><span class="hl-identifier">text </span><span class="hl-reserved">is not None</span><span class="hl-default">:
       </span><span class="hl-reserved">print </span><span class="hl-identifier">element</span><span class="hl-default">.</span><span class="hl-identifier">text</span></pre></div></div>
<h2><a href="#ReadingXMLAttributes">Reading XML Attributes</a></h2>
<p>Let&#8217;s alter the XML that we are working with to add attributes to the elements and look at how we would parse that information.</p>
<p>If the XML uses attributes in addition to, or instead of, inner text they can be accessed using the Element object&#8217;s <code>attrib</code> attribute.  The <code>attrib</code> attribute is a Python dictionary and is relatively easy to use:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">main</span><span class="hl-brackets">()</span><span class="hl-default">:
       </span><span class="hl-identifier">element</span><span class="hl-default"> = </span><span class="hl-identifier">ET</span><span class="hl-default">.</span><span class="hl-identifier">XML</span><span class="hl-brackets">(
               </span><span class="hl-quotes">'</span><span class="hl-string">&lt;root&gt;&lt;child val=&quot;One&quot;/&gt;&lt;child val=&quot;Two&quot;/&gt;&lt;/root&gt;</span><span class="hl-quotes">'</span><span class="hl-brackets">)
       </span><span class="hl-reserved">for </span><span class="hl-identifier">subelement </span><span class="hl-reserved">in </span><span class="hl-identifier">element</span><span class="hl-default">:
               </span><span class="hl-reserved">print </span><span class="hl-identifier">subelement</span><span class="hl-default">.</span><span class="hl-identifier">attrib</span></pre></div></div>
<p>When you run the code you get the following output:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-default">{</span><span class="hl-quotes">'</span><span class="hl-string">val</span><span class="hl-quotes">'</span><span class="hl-default">: </span><span class="hl-quotes">'</span><span class="hl-string">One</span><span class="hl-quotes">'</span><span class="hl-default">}
{</span><span class="hl-quotes">'</span><span class="hl-string">val</span><span class="hl-quotes">'</span><span class="hl-default">: </span><span class="hl-quotes">'</span><span class="hl-string">Two</span><span class="hl-quotes">'</span><span class="hl-default">}</span></pre></div></div>
<p>These are the attributes for each child element stored in a dictionary. Being able to work with an XML element&#8217;s attributes as a Python dictionary is a great feature and fits well with the dynamic nature of XML attributes.</p>
<h2><a href="#WritingXML">Writing XML</a></h2>
<p>Now that we&#8217;ve tried our hand at reading XML, let&#8217;s try creating some. If you understand the reading process, you should have no trouble understanding the creation process because it works in much the same manner. What we are going to do in this example is recreate the XML data that we were working with above.</p>
<p>The first step is to create our <code><root></root></code> element:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-comment">#create the root &lt;root&gt;
</span><span class="hl-identifier">root_element</span><span class="hl-default"> = </span><span class="hl-identifier">ET</span><span class="hl-default">.</span><span class="hl-identifier">Element</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">root</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span></pre></div></div>
<p>After this code is executed, the variable <code>root_element</code> is an Element object, just like the Element objects that we used earlier to parse the XML.</p>
<p>The next step is to create the two child elements. There are two ways to do this.</p>
<p>In the first method, if you know exactly what you are creating, it&#8217;s easiest to use the <code>SubElement</code> method, which creates an Element object that is a subelement (or child) of another Element object:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-comment">#create the first child &lt;child&gt;One&lt;/child&gt;
</span><span class="hl-identifier">child</span><span class="hl-default"> = </span><span class="hl-identifier">ET</span><span class="hl-default">.</span><span class="hl-identifier">SubElement</span><span class="hl-brackets">(</span><span class="hl-identifier">root_element</span><span class="hl-code">, </span><span class="hl-quotes">&quot;</span><span class="hl-string">child</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span></pre></div></div>
<p>This will create a <code><child></child></code> Element that is a child of <code>root_element</code>.  We then need to set the text associated with that element.  To do this we use the same text attribute that we used in the first parsing example. However, instead of simply reading the text attribute we set its value:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">child</span><span class="hl-default">.</span><span class="hl-identifier">text</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;</span><span class="hl-string">One</span><span class="hl-quotes">&quot;</span></pre></div></div>
<p>The second approach to creating a child element is to create an Element object separately (rather than a sub element) and append it to a parent Element object.  The results are exactly the same &#8211; this is simply a different approach that may come in handy when creating your XML,or working with two sets of XML data.</p>
<p>First we create an Element object in the same way that we created the root element:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-comment">#create the second child &lt;child&gt;Two&lt;/child&gt;
</span><span class="hl-identifier">child</span><span class="hl-default"> = </span><span class="hl-identifier">ET</span><span class="hl-default">.</span><span class="hl-identifier">Element</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">child</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
</span><span class="hl-identifier">child</span><span class="hl-default">.</span><span class="hl-identifier">text</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;</span><span class="hl-string">Two</span><span class="hl-quotes">&quot;</span></pre></div></div>
<p>This creates the <code>child</code> Element object and sets its text to &#8220;Two&#8221;.  We then append it to the root element: </p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-comment">#now append
</span><span class="hl-identifier">root_element</span><span class="hl-default">.</span><span class="hl-identifier">append</span><span class="hl-brackets">(</span><span class="hl-identifier">child</span><span class="hl-brackets">)</span></pre></div></div>
<p>Pretty simple!  Now, if we want to look at the contents of our <code>root_element</code> (or any other Element object for that matter) we can use the handy <code>tostring</code> function. It does exactly what it says that it does: it converts an Element object into a human readable string.</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-comment">#Let's see the results
</span><span class="hl-reserved">print </span><span class="hl-identifier">ET</span><span class="hl-default">.</span><span class="hl-identifier">tostring</span><span class="hl-brackets">(</span><span class="hl-identifier">root_element</span><span class="hl-brackets">)</span></pre></div></div>
<p><strong><a href="#Listing3">Listing 3</a></strong></p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-comment">#!/usr/bin/env python

</span><span class="hl-reserved">from </span><span class="hl-identifier">xml</span><span class="hl-default">.</span><span class="hl-identifier">etree </span><span class="hl-reserved">import </span><span class="hl-identifier">ElementTree as ET

</span><span class="hl-reserved">def </span><span class="hl-identifier">main</span><span class="hl-brackets">()</span><span class="hl-default">:
	</span><span class="hl-comment">#create the root &lt;/root&gt;&lt;root&gt;
	</span><span class="hl-identifier">root_element</span><span class="hl-default"> = </span><span class="hl-identifier">ET</span><span class="hl-default">.</span><span class="hl-identifier">Element</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">root</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
	</span><span class="hl-comment">#create the first child &lt;child&gt;One&lt;/child&gt;
	</span><span class="hl-identifier">child</span><span class="hl-default"> = </span><span class="hl-identifier">ET</span><span class="hl-default">.</span><span class="hl-identifier">SubElement</span><span class="hl-brackets">(</span><span class="hl-identifier">root_element</span><span class="hl-code">, </span><span class="hl-quotes">&quot;</span><span class="hl-string">child</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
	</span><span class="hl-identifier">child</span><span class="hl-default">.</span><span class="hl-identifier">text</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;</span><span class="hl-string">One</span><span class="hl-quotes">&quot;
	</span><span class="hl-comment">#create the second child &lt;child&gt;Two&lt;/child&gt;
	</span><span class="hl-identifier">child</span><span class="hl-default"> = </span><span class="hl-identifier">ET</span><span class="hl-default">.</span><span class="hl-identifier">Element</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">child</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
	</span><span class="hl-identifier">child</span><span class="hl-default">.</span><span class="hl-identifier">text</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;</span><span class="hl-string">Two</span><span class="hl-quotes">&quot;
	</span><span class="hl-comment">#now append
	</span><span class="hl-identifier">root_element</span><span class="hl-default">.</span><span class="hl-identifier">append</span><span class="hl-brackets">(</span><span class="hl-identifier">child</span><span class="hl-brackets">)
	</span><span class="hl-comment">#Let's see the results
	</span><span class="hl-reserved">print </span><span class="hl-identifier">ET</span><span class="hl-default">.</span><span class="hl-identifier">tostring</span><span class="hl-brackets">(</span><span class="hl-identifier">root_element</span><span class="hl-brackets">)

</span><span class="hl-reserved">if </span><span class="hl-identifier">__name__</span><span class="hl-default"> == </span><span class="hl-quotes">&quot;</span><span class="hl-string">__main__</span><span class="hl-quotes">&quot;</span><span class="hl-default">:
	</span><span class="hl-comment"># Someone is launching this directly
	</span><span class="hl-identifier">main</span><span class="hl-brackets">()</span></pre></div></div>
<p>To recap, have a look at the code in Listing 3. When you run this code you will get the following output:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-default">&lt;/</span><span class="hl-identifier">root</span><span class="hl-default">&gt;&lt;</span><span class="hl-identifier">root</span><span class="hl-default">&gt;&lt;</span><span class="hl-identifier">child</span><span class="hl-default">&gt;</span><span class="hl-identifier">One</span><span class="hl-default">&lt;/</span><span class="hl-identifier">child</span><span class="hl-default">&gt;&lt;</span><span class="hl-identifier">child</span><span class="hl-default">&gt;</span><span class="hl-identifier">Two</span><span class="hl-default">&lt;/</span><span class="hl-identifier">child</span><span class="hl-default">&gt;&lt;/</span><span class="hl-identifier">root</span><span class="hl-default">&gt;</span></pre></div></div>
<h2><a href="#WritingXMLAttributes">Writing XML Attributes</a></h2>
<p>If you want to create the XML with attributes (as illustrated in the second reading example), you can use the Element object&#8217;s <code>set</code> method.  To add the <code>val</code> attribute to the first element, use the following:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">child</span><span class="hl-default">.</span><span class="hl-identifier">set</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">val</span><span class="hl-quotes">&quot;</span><span class="hl-code">,</span><span class="hl-quotes">&quot;</span><span class="hl-string">One</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span></pre></div></div>
<p>You may also set attributes when you create Element objects:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">child</span><span class="hl-default"> = </span><span class="hl-identifier">ET</span><span class="hl-default">.</span><span class="hl-identifier">Element</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">child</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-identifier">val</span><span class="hl-code">=</span><span class="hl-quotes">&quot;</span><span class="hl-string">One</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span></pre></div></div>
<h2><a href="#ReadingXMLFiles">Reading XML Files</a></h2>
<p>Most of the time you won&#8217;t be working with XML data that you explicitly create in your code, instead you will usually read the XML data in from a data source, work with it, and then save it back out when you are done. Fortunately, configuring <em>ElementTree</em> to work with different data sources is very easy.  For example, let&#8217;s take the XML data that we first used and save it into a file named <code>our.xml</code> in the same location as our Python file.</p>
<p>There are a few methods that we can use to load XML data from a file. We are going to use the <code>parse</code> function. This function is nice because it will accept, as a parameter, the path to a file OR a &#8220;file-like&#8221; object.  The term &#8220;file-like&#8221; is used on purpose because the object does not have to be a file object per se &#8211; it simply has to be an object that behaves in a file-like manner. A &#8220;file-like&#8221; object is an object that implements a &#8220;file-like&#8221; interface, meaning that it shares many (if not all) methods with the file object. If an object is &#8220;file-like&#8221; this fact will usually be prominently mentioned in its documentation.</p>
<p>The first thing that we need in order to load the XML data is determine the full path to the <code>our.xml</code> file. In order to calculate this, we determine the full path of our Python source file, strip the filename from it, and then append <code>our.xml</code> to the path. This is rather simple given that the <code>__file__</code> attribute (available in Python 2.2 and later) is the relative path and filename of our Python source file. Although the <code>__file__</code> attribute will be a relative path, we can use it to calculate the absolute path using the standard <em>os</em> module:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-reserved">import </span><span class="hl-identifier">os</span></pre></div></div>
<p>We then call the <code>abspath</code> function to get the absolute path:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">xml_file</span><span class="hl-default"> = </span><span class="hl-identifier">os</span><span class="hl-default">.</span><span class="hl-identifier">path</span><span class="hl-default">.</span><span class="hl-identifier">abspath</span><span class="hl-brackets">(</span><span class="hl-identifier">__file__</span><span class="hl-brackets">)</span></pre></div></div>
<p>However, since we only want the directory name (not the full path and filename of our Python source file) we have to strip off the filename:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">xml_file</span><span class="hl-default"> = </span><span class="hl-identifier">os</span><span class="hl-default">.</span><span class="hl-identifier">path</span><span class="hl-default">.</span><span class="hl-identifier">dirname</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)</span></pre></div></div>
<p>Now that we have the directory in which the <code>our.xml</code> file resides, all we have to do is append the <code>our.xml</code> filename to the <code>xml_file</code> variable.  However, instead of just doing something like:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">xml_file</span><span class="hl-default"> += </span><span class="hl-quotes">&quot;</span><span class="hl-string">/our.xml</span><span class="hl-quotes">&quot;</span></pre></div></div>
<p>we will use the <em>os</em> module to join the two paths so that the resulting path is always correct regardless of what operating system our code is executed on:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">xml_file</span><span class="hl-default"> = </span><span class="hl-identifier">os</span><span class="hl-default">.</span><span class="hl-identifier">path</span><span class="hl-default">.</span><span class="hl-identifier">join</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-code">, </span><span class="hl-quotes">&quot;</span><span class="hl-string">our.xml</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span></pre></div></div>
<p><strong>Note</strong>: If you have any trouble understanding what any of the code used to determine the path of <code>our.xml</code> is doing, try printing out <code>xml_file</code> after each of the above lines and it should become clear.</p>
<p>We now have the full path to the <code>our.xml</code> file.  In order to load its XML data we simply pass the path to the <code>parse</code> function:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">tree</span><span class="hl-default"> = </span><span class="hl-identifier">ET</span><span class="hl-default">.</span><span class="hl-identifier">parse</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)</span></pre></div></div>
<p>We now have an ElementTree object instance that represents our XML file.</p>
<p>Since we are working with files, we should watch out for incorrect paths, I/O errors, or the parse function failing for any other reason.  If you wish to be extra careful, you can wrap the parse function in a try/except block in order to catch any exceptions that may be thrown:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">try</span><span class="hl-default">:
       </span><span class="hl-identifier">tree</span><span class="hl-default"> = </span><span class="hl-identifier">ET</span><span class="hl-default">.</span><span class="hl-identifier">parse</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">sar</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
</span><span class="hl-reserved">except Exception</span><span class="hl-default">, </span><span class="hl-identifier">inst</span><span class="hl-default">:
       </span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-string">Unexpected error opening %s: %s</span><span class="hl-quotes">&quot;</span><span class="hl-default"> % </span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-code">, </span><span class="hl-identifier">inst</span><span class="hl-brackets">)
       </span><span class="hl-reserved">return</span></pre></div></div>
<p>In the except block, I catch the Exception base class so that I catch any and all exceptions that may be thrown (in the case of a missing file it will most likely be an <code>IOError</code> exception).</p>
<h2><a href="#WritingXMLDatatoaFile">Writing XML Data to a File</a></h2>
<p>Now that we know how to read in XML data, we should look at how one writes XML data out to a file.  Let&#8217;s assume that after reading in the <code>out.xml</code> fiie we want to add another item to the XML file that we just read in:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">child</span><span class="hl-default"> = </span><span class="hl-identifier">ET</span><span class="hl-default">.</span><span class="hl-identifier">SubElement</span><span class="hl-brackets">(</span><span class="hl-identifier">tree</span><span class="hl-code">.</span><span class="hl-identifier">getroot</span><span class="hl-brackets">()</span><span class="hl-code">, </span><span class="hl-quotes">&quot;</span><span class="hl-string">child</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
</span><span class="hl-identifier">child</span><span class="hl-default">.</span><span class="hl-identifier">text</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;</span><span class="hl-string">Three</span><span class="hl-quotes">&quot;</span></pre></div></div>
<p>Notice that in order to add a child to the root element we used the ElementTree object&#8217;s <code>getroot</code> function. The <code>getroot</code> function simply returns the root Element object of the XML data.</p>
<p>Now that we have a third child element, let&#8217;s write the XML data back out to <code>our.xml</code>. Thanks to <em>ElementTree</em> this is a painless experience:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">tree</span><span class="hl-default">.</span><span class="hl-identifier">write</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)</span></pre></div></div>
<p>That&#8217;s it!</p>
<p>If we want to be really careful when writing the XML data out to a file, we&#8217;ll watch out for exceptions. However most of the time the <code>write</code> method will succeed without throwing an exception; it is more important to be sure that the path used is correct.  Often times, instead of getting the exception that you want, you end up with an XML file stored in some far off and strange location on your hard drive because your path was incorrect or you did not specify the full path.  But, as is often the case when programming, better safe than sorry:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">try</span><span class="hl-default">:
       </span><span class="hl-identifier">tree</span><span class="hl-default">.</span><span class="hl-identifier">write</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)
</span><span class="hl-reserved">except Exception</span><span class="hl-default">, </span><span class="hl-identifier">inst</span><span class="hl-default">:
       </span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-string">Unexpected error writing to file %s: %s</span><span class="hl-quotes">&quot;</span><span class="hl-default"> % </span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-code">, </span><span class="hl-identifier">inst</span><span class="hl-brackets">)
       </span><span class="hl-reserved">return</span></pre></div></div>
<p>To recap you can find all of the code from this section in Listing 4.</p>
<p><strong><a href="#Listing4">Listing 4</a></strong></p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-comment">#!/usr/bin/env python

</span><span class="hl-reserved">from </span><span class="hl-identifier">xml</span><span class="hl-default">.</span><span class="hl-identifier">etree </span><span class="hl-reserved">import </span><span class="hl-identifier">ElementTree as ET
</span><span class="hl-reserved">import </span><span class="hl-identifier">os

</span><span class="hl-reserved">def </span><span class="hl-identifier">main</span><span class="hl-brackets">()</span><span class="hl-default">:

	</span><span class="hl-identifier">xml_file</span><span class="hl-default"> = </span><span class="hl-identifier">os</span><span class="hl-default">.</span><span class="hl-identifier">path</span><span class="hl-default">.</span><span class="hl-identifier">abspath</span><span class="hl-brackets">(</span><span class="hl-identifier">__file__</span><span class="hl-brackets">)
	</span><span class="hl-identifier">xml_file</span><span class="hl-default"> = </span><span class="hl-identifier">os</span><span class="hl-default">.</span><span class="hl-identifier">path</span><span class="hl-default">.</span><span class="hl-identifier">dirname</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)
	</span><span class="hl-identifier">xml_file</span><span class="hl-default"> = </span><span class="hl-identifier">os</span><span class="hl-default">.</span><span class="hl-identifier">path</span><span class="hl-default">.</span><span class="hl-identifier">join</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-code">, </span><span class="hl-quotes">&quot;</span><span class="hl-string">our.xml</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)

	</span><span class="hl-reserved">try</span><span class="hl-default">:
		</span><span class="hl-identifier">tree</span><span class="hl-default"> = </span><span class="hl-identifier">ET</span><span class="hl-default">.</span><span class="hl-identifier">parse</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)
	</span><span class="hl-reserved">except Exception</span><span class="hl-default">, </span><span class="hl-identifier">inst</span><span class="hl-default">:
		</span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-string">Unexpected error opening %s: %s</span><span class="hl-quotes">&quot;</span><span class="hl-default"> % </span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-code">, </span><span class="hl-identifier">inst</span><span class="hl-brackets">)
		</span><span class="hl-reserved">return

	</span><span class="hl-identifier">child</span><span class="hl-default"> = </span><span class="hl-identifier">ET</span><span class="hl-default">.</span><span class="hl-identifier">SubElement</span><span class="hl-brackets">(</span><span class="hl-identifier">tree</span><span class="hl-code">.</span><span class="hl-identifier">getroot</span><span class="hl-brackets">()</span><span class="hl-code">, </span><span class="hl-quotes">&quot;</span><span class="hl-string">child</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
	</span><span class="hl-identifier">child</span><span class="hl-default">.</span><span class="hl-identifier">text</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;</span><span class="hl-string">Three</span><span class="hl-quotes">&quot;

	</span><span class="hl-reserved">try</span><span class="hl-default">:
		</span><span class="hl-identifier">tree</span><span class="hl-default">.</span><span class="hl-identifier">write</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)
	</span><span class="hl-reserved">except Exception</span><span class="hl-default">, </span><span class="hl-identifier">inst</span><span class="hl-default">:
		</span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-string">Unexpected error writing to file %s: %s</span><span class="hl-quotes">&quot;</span><span class="hl-default"> % </span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-code">, </span><span class="hl-identifier">inst</span><span class="hl-brackets">)
		</span><span class="hl-reserved">return

if </span><span class="hl-identifier">__name__</span><span class="hl-default"> == </span><span class="hl-quotes">&quot;</span><span class="hl-string">__main__</span><span class="hl-quotes">&quot;</span><span class="hl-default">:
	</span><span class="hl-comment"># Someone is launching this directly
	</span><span class="hl-identifier">main</span><span class="hl-brackets">()</span></pre></div></div>
<p>When you run the code and take a look at the <code>our.xml</code> file you should see that the the third child element has been added:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-default">&lt;</span><span class="hl-identifier">root</span><span class="hl-default">&gt;
&lt;</span><span class="hl-identifier">child</span><span class="hl-default">&gt;</span><span class="hl-identifier">One</span><span class="hl-default">&lt;/</span><span class="hl-identifier">child</span><span class="hl-default">&gt;
&lt;</span><span class="hl-identifier">child</span><span class="hl-default">&gt;</span><span class="hl-identifier">Two</span><span class="hl-default">&lt;/</span><span class="hl-identifier">child</span><span class="hl-default">&gt;
&lt;</span><span class="hl-identifier">child</span><span class="hl-default">&gt;</span><span class="hl-identifier">Three</span><span class="hl-default">&lt;/</span><span class="hl-identifier">child</span><span class="hl-default">&gt;
&lt;/</span><span class="hl-identifier">root</span><span class="hl-default">&gt;</span></pre></div></div>
<h2><a href="#ReadingfromtheWeb">Reading from the Web</a></h2>
<p>Working with a local file is very useful, but you might also be in a situation where you will have to work with an XML file that is located on the Internet, perhaps an RSS feed.  Fortunately, since the <code>parse</code> function explained above works with file-like elements, loading a URL is very easy.</p>
<p>First off, you need to import the <em>urllib</em> module; a standard module that allows you to open URLs in a method similar to opening local files:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-reserved">import </span><span class="hl-identifier">urllib</span></pre></div></div>
<p>In order to open a URL we use:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">feed</span><span class="hl-default"> = </span><span class="hl-identifier">urllib</span><span class="hl-default">.</span><span class="hl-identifier">urlopen</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">http://pythonmagazine.com/c/news/atom</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
</span><span class="hl-identifier">tree</span><span class="hl-default"> = </span><span class="hl-identifier">ET</span><span class="hl-default">.</span><span class="hl-identifier">parse</span><span class="hl-brackets">(</span><span class="hl-identifier">feed</span><span class="hl-brackets">)</span></pre></div></div>
<h2><a href="#Conclusion">Conclusion</a></h2>
<p>And that&#8217;s that!  This concludes our brief introduction to XML parsing using the <em>ElementTree</em> module. Hopefully throughout this article you have seen how easy it is to create and manipulate XML using <em>ElementTree</em> &#8230;and I&#8217;ve only scratched the surface.  For more information take a look at the official Python documentation and some of the great examples on the effbot website. I&#8217;m sure you&#8217;ll be an XML wizard in no time.</p>
<p>[1] <a href="http://docs.python.org/whatsnew/modules.html#SECTION0001420000000000000000">http://docs.python.org/whatsnew/modules.html#SECTION0001420000000000000000</a><br />
[2] <a href="http://effbot.org/zone/pythondoc-elementtree-ElementTree.htm#elementtree.ElementTree.XML-function">http://effbot.org/zone/pythondoc-elementtree-ElementTree.htm#elementtree.ElementTree.XML-function</a><br />
[3] <a href="http://effbot.org/zone/pythondoc-elementtree-ElementTree.htm#elementtree.ElementTree.ElementTree-class">http://effbot.org/zone/pythondoc-elementtree-ElementTree.htm#elementtree.ElementTree.ElementTree-class</a></p>
<div style="float:right;margin:0px 0px 0px 0px;"><a href="http://www.google.com/reader/link?url=http://www.learningpython.com/2008/05/07/elegant-xml-parsing-using-the-elementtree-module/&title=Elegant XML parsing using the ElementTree Module&srcTitle=learning python&srcURL=http://www.learningpython.com"target="_blank" rel=""><img border="0" src="http://www.learningpython.com/wp-content/plugins/wp-google-buzz/icon/12.png" style="opacity:1;filter:alpha(opacity=100)" onmouseover="this.style.opacity=0.8;this.filters.alpha.opacity=70" onmouseout="this.style.opacity=1;this.filters.alpha.opacity=100"/> </a></div>]]></content:encoded>
			<wfw:commentRss>http://www.learningpython.com/2008/05/07/elegant-xml-parsing-using-the-elementtree-module/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>WordPy 0.2 &#8211; Using XML to Save and Load Data</title>
		<link>http://www.learningpython.com/2006/10/24/wordpy-02-using-xml-to-save-and-load-data/</link>
		<comments>http://www.learningpython.com/2006/10/24/wordpy-02-using-xml-to-save-and-load-data/#comments</comments>
		<pubDate>Wed, 25 Oct 2006 02:22:52 +0000</pubDate>
		<dc:creator>selsine</dc:creator>
				<category><![CDATA[PyGTK]]></category>
		<category><![CDATA[WordPy]]></category>
		<category><![CDATA[glade]]></category>
		<category><![CDATA[gui]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[reference]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://www.learningpython.com/?p=41</guid>
		<description><![CDATA[
			
				
			
		
All right, so we have our base WordPy application running, so let&#8217;s try to extend it a bit more by letting you load and save blog posts to and from an xml file.  Please note that this tutorial simply shows one method of saving and loading data using xml, there are many different methods [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.learningpython.com%2F2006%2F10%2F24%2Fwordpy-02-using-xml-to-save-and-load-data%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.learningpython.com%2F2006%2F10%2F24%2Fwordpy-02-using-xml-to-save-and-load-data%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>All right, so we have our base WordPy application running, so let&#8217;s try to extend it a bit more by letting you load and save blog posts to and from an xml file.  Please note that this tutorial simply shows one method of saving and loading data using xml, there are many different methods and this method was chosen for its simplicity.</p>
<p>If you are unfamiliar with the <a href="http://www.learningpython.com/2006/08/19/wordpress-python-library/">first WordPy tutorial</a> you should probably read it fist in order to have a better understanding of some of what happens in this tutorial. </p>
<p>You can download the complete code for this tutorial <a href="http://www.learningpython.com/sources/WordPy_0_2.tar.gz">here</a>.</p>
<h2>The GUI</h2>
<p>The first thing we need to-do is open up the wordpy glade project and make some changes:</p>
<ol>
<li>We&#8217;ll start off by adding another item to our VBox in Glade.  You can do this by holding down shift and clicking on the WordPy window until you see the GTKVBox come up in the properties window.  Then simply change it&#8217;s size value from 4 to 5.</li>
<li>In the empty space add a menu bar.  Then on the Packing tab of the menu bar&#8217;s properties set the position to be zero, so that the menu is at the top of the window.</li>
<li>Then edit the menu so that only the  File, Edit, and Help menu&#8217;s remain.</li>
<li>Add handlers to each of the files menu items: on_file_new, on_file_open, on_file_save, on_file_save_as</li>
</ol>
<p><img style="margin: 0pt 10px 10px 0pt;" src="http://www.learningpython.com/images/WordPy_02/wordpy_02_01.png" alt="GLADE Window PyWine" border="0" /></p>
<h2>The Code</h2>
<p>That&#8217;s it for editing the GUI, now we have to go and edit the code.  The first step is to connect all of the menu events with our code:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">dic</span><span class="hl-default"> = {</span><span class="hl-quotes">&quot;</span><span class="hl-string">on_wndMain_destroy</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">quit</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnBold_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnBold_clicked</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnItalic_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnItalic_clicked</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnLink_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnLink_clicked</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnBlockQuote_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnBlockQuote_clicked</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnDel_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnDel_clicked</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnIns_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnIns_clicked</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnImage_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnImage_clicked</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnUnorderedList_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnUnorderedList_clicked</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnOrderedList_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnOrderedList_clicked</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnListItem_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnListItem_clicked</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnCode_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnCode_clicked</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnMore_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnMore_clicked</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnSettings_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnSettings_clicked</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnpost_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnpost_clicked</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_file_new</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_file_new</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_file_open</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_file_open</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_file_save</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_file_save</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_file_save_as</span><span class="hl-quotes">&quot;</span><span class="hl-default">: </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_file_save_as</span><span class="hl-default">}
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">wTree</span><span class="hl-default">.</span><span class="hl-identifier">signal_autoconnect</span><span class="hl-brackets">(</span><span class="hl-identifier">dic</span><span class="hl-brackets">)</span></pre></div></div>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">on_file_new</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:

</span><span class="hl-reserved">def </span><span class="hl-identifier">on_file_open</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:

</span><span class="hl-reserved">def </span><span class="hl-identifier">on_file_save</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:

</span><span class="hl-reserved">def </span><span class="hl-identifier">on_file_save_as</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">. </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:</span></pre></div></div>
<p><span id="more-41"></span></p>
<p>Now when we save and load the post we will need to use the same xml tags, so instead of typing them twice (or in case we want to change them) I decided to save them as a dictionary in the WordPy class:</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-identifier">MAIN_TAG</span><span class="hl-default"> = </span><span class="hl-number">0
</span><span class="hl-identifier">POST_TAG</span><span class="hl-default"> = </span><span class="hl-number">1
</span><span class="hl-identifier">TITLE_TAG</span><span class="hl-default"> = </span><span class="hl-number">2
</span><span class="hl-identifier">TEXT_TAG</span><span class="hl-default"> = </span><span class="hl-number">3
</span><span class="hl-identifier">SETTINGS_TAG</span><span class="hl-default"> = </span><span class="hl-number">4
</span><span class="hl-identifier">URL_TAG</span><span class="hl-default"> = </span><span class="hl-number">5
</span><span class="hl-identifier">USERNAME_TAG</span><span class="hl-default"> = </span><span class="hl-number">6
</span><span class="hl-identifier">PASSWORD_TAG</span><span class="hl-default"> = </span><span class="hl-number">7

</span><span class="hl-reserved">class </span><span class="hl-identifier">WordPy</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">This is the Wordpy application.  It is a simple PyGTK
	application that interacts with the WorPress Python library.</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-identifier">_xml_tags</span><span class="hl-default"> = {
			</span><span class="hl-identifier">MAIN_TAG</span><span class="hl-default"> : </span><span class="hl-quotes">&quot;</span><span class="hl-string">WordPy</span><span class="hl-quotes">&quot;</span><span class="hl-default">
			, </span><span class="hl-identifier">POST_TAG</span><span class="hl-default"> : </span><span class="hl-quotes">&quot;</span><span class="hl-string">Post</span><span class="hl-quotes">&quot;</span><span class="hl-default">
			, </span><span class="hl-identifier">TITLE_TAG</span><span class="hl-default"> : </span><span class="hl-quotes">&quot;</span><span class="hl-string">Title</span><span class="hl-quotes">&quot;</span><span class="hl-default">
			, </span><span class="hl-identifier">TEXT_TAG</span><span class="hl-default"> : </span><span class="hl-quotes">&quot;</span><span class="hl-string">Text</span><span class="hl-quotes">&quot;</span><span class="hl-default">
			, </span><span class="hl-identifier">URL_TAG</span><span class="hl-default"> : </span><span class="hl-quotes">&quot;</span><span class="hl-string">URL</span><span class="hl-quotes">&quot;</span><span class="hl-default">
			, </span><span class="hl-identifier">SETTINGS_TAG</span><span class="hl-default"> : </span><span class="hl-quotes">&quot;</span><span class="hl-string">Settings</span><span class="hl-quotes">&quot;</span><span class="hl-default">
			, </span><span class="hl-identifier">USERNAME_TAG</span><span class="hl-default"> : </span><span class="hl-quotes">&quot;</span><span class="hl-string">Username</span><span class="hl-quotes">&quot;</span><span class="hl-default">
			, </span><span class="hl-identifier">PASSWORD_TAG</span><span class="hl-default"> : </span><span class="hl-quotes">&quot;</span><span class="hl-string">password</span><span class="hl-quotes">&quot;</span><span class="hl-default">
	}</span></pre></div></div>
<p>Now when we save and load we can get the username xml tag like so:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">USERNAME_TAG</span><span class="hl-brackets">]</span></pre></div></div>
<p>And if someone wants to import WordPy into their own Python project, they could get at the tags (if they didn&#8217;t have a WordPy object instantiated) like so:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">WordPy</span><span class="hl-default">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">USERNAME_TAG</span><span class="hl-brackets">]</span></pre></div></div>
<p>We also need to add a new element in the __init__() function:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">xml_file</span><span class="hl-default"> = </span><span class="hl-reserved">None</span></pre></div></div>
<p>This will be the full path to the xml file that is represents the current post, it starts off as None, since when we first start WordPy the blank post is not associated with any xml file.</p>
<p>We will also need to do some file browsing for the save, open, and save as events so we&#8217;ll borrow the file_browse() function from the <a href="http://www.learningpython.com/2006/09/02/extending-our-pygtk-application/">Extending our PyGTK application</a> tutorial (to learn more about the function and how it works please read the tutorial):</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-comment"># Borrowed from the PyWine project
</span><span class="hl-reserved">def </span><span class="hl-identifier">file_browse</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">dialog_action</span><span class="hl-code">, </span><span class="hl-identifier">file_name</span><span class="hl-code">=</span><span class="hl-quotes">&quot;&quot;</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">This function is used to browse for a pyWine file.
	It can be either a save or open dialog depending on
	what dialog_action is.
	The path to the file will be returned if the user
	selects one, however a blank string will be returned
	if they cancel or do not select one.
	dialog_action - The open or save mode for the dialog either
	gtk.FILE_CHOOSER_ACTION_OPEN, gtk.FILE_CHOOSER_ACTION_SAVE
	@param file_name - Default name when doing a save
	@returns - File Name, or None on cancel.
	</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">dialog_action</span><span class="hl-code">==</span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">FILE_CHOOSER_ACTION_OPEN</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">dialog_buttons</span><span class="hl-default"> = </span><span class="hl-brackets">(</span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">STOCK_CANCEL</span><span class="hl-code">
			, </span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">RESPONSE_CANCEL</span><span class="hl-code">
			, </span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">STOCK_OPEN</span><span class="hl-code">
			, </span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">RESPONSE_OK</span><span class="hl-brackets">)
		</span><span class="hl-identifier">dlg_title</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;</span><span class="hl-string">Open Post</span><span class="hl-quotes">&quot;
	</span><span class="hl-reserved">else</span><span class="hl-default">:
		</span><span class="hl-identifier">dialog_buttons</span><span class="hl-default"> = </span><span class="hl-brackets">(</span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">STOCK_CANCEL</span><span class="hl-code">
			, </span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">RESPONSE_CANCEL</span><span class="hl-code">
			, </span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">STOCK_SAVE</span><span class="hl-code">
			, </span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">RESPONSE_OK</span><span class="hl-brackets">)
		</span><span class="hl-identifier">dlg_title</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;</span><span class="hl-string">Save Post</span><span class="hl-quotes">&quot;

	</span><span class="hl-identifier">file_dialog</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">FileChooserDialog</span><span class="hl-brackets">(</span><span class="hl-identifier">title</span><span class="hl-code">=</span><span class="hl-identifier">dlg_title</span><span class="hl-code">
		, </span><span class="hl-identifier">action</span><span class="hl-code">=</span><span class="hl-identifier">dialog_action</span><span class="hl-code">
		, </span><span class="hl-identifier">buttons</span><span class="hl-code">=</span><span class="hl-identifier">dialog_buttons</span><span class="hl-brackets">)
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">set the filename if we are saving</span><span class="hl-quotes">&quot;&quot;&quot;
	</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">dialog_action</span><span class="hl-code">==</span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">FILE_CHOOSER_ACTION_SAVE</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">file_dialog</span><span class="hl-default">.</span><span class="hl-identifier">set_current_name</span><span class="hl-brackets">(</span><span class="hl-identifier">file_name</span><span class="hl-brackets">)
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Create and add the pywine filter</span><span class="hl-quotes">&quot;&quot;&quot;
	</span><span class="hl-identifier">filter</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">FileFilter</span><span class="hl-brackets">()
	</span><span class="hl-identifier">filter</span><span class="hl-default">.</span><span class="hl-identifier">set_name</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">WordPy Post</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
	</span><span class="hl-identifier">filter</span><span class="hl-default">.</span><span class="hl-identifier">add_pattern</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">*.</span><span class="hl-quotes">&quot;</span><span class="hl-code"> + </span><span class="hl-identifier">FILE_EXT</span><span class="hl-brackets">)
	</span><span class="hl-identifier">file_dialog</span><span class="hl-default">.</span><span class="hl-identifier">add_filter</span><span class="hl-brackets">(</span><span class="hl-identifier">filter</span><span class="hl-brackets">)
	</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">dialog_action</span><span class="hl-code">==</span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">FILE_CHOOSER_ACTION_OPEN</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Create and add the 'all files' filter</span><span class="hl-quotes">&quot;&quot;&quot;
		</span><span class="hl-identifier">filter</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">FileFilter</span><span class="hl-brackets">()
		</span><span class="hl-identifier">filter</span><span class="hl-default">.</span><span class="hl-identifier">set_name</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">All files</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
		</span><span class="hl-identifier">filter</span><span class="hl-default">.</span><span class="hl-identifier">add_pattern</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">*</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
		</span><span class="hl-identifier">file_dialog</span><span class="hl-default">.</span><span class="hl-identifier">add_filter</span><span class="hl-brackets">(</span><span class="hl-identifier">filter</span><span class="hl-brackets">)

	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Init the return value</span><span class="hl-quotes">&quot;&quot;&quot;
	</span><span class="hl-identifier">result</span><span class="hl-default"> = </span><span class="hl-reserved">None
	if </span><span class="hl-identifier">file_dialog</span><span class="hl-default">.</span><span class="hl-identifier">run</span><span class="hl-brackets">()</span><span class="hl-default"> == </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">RESPONSE_OK</span><span class="hl-default">:
		</span><span class="hl-identifier">result</span><span class="hl-default"> = </span><span class="hl-identifier">file_dialog</span><span class="hl-default">.</span><span class="hl-identifier">get_filename</span><span class="hl-brackets">()
		</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">dialog_action</span><span class="hl-code">==</span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">FILE_CHOOSER_ACTION_SAVE</span><span class="hl-brackets">)</span><span class="hl-default">:
			</span><span class="hl-identifier">result</span><span class="hl-default">, </span><span class="hl-identifier">extension</span><span class="hl-default"> = </span><span class="hl-identifier">os</span><span class="hl-default">.</span><span class="hl-identifier">path</span><span class="hl-default">.</span><span class="hl-identifier">splitext</span><span class="hl-brackets">(</span><span class="hl-identifier">result</span><span class="hl-brackets">)
			</span><span class="hl-identifier">result</span><span class="hl-default"> = </span><span class="hl-identifier">result</span><span class="hl-default"> + </span><span class="hl-quotes">&quot;</span><span class="hl-string">.</span><span class="hl-quotes">&quot;</span><span class="hl-default"> + </span><span class="hl-identifier">FILE_EXT
	file_dialog</span><span class="hl-default">.</span><span class="hl-identifier">destroy</span><span class="hl-brackets">()

	</span><span class="hl-reserved">return </span><span class="hl-identifier">result</span></pre></div></div>
<p>Note that this function is somewhat different then the original in that it returns None if the users cancels the operation rather then returning a blank string.</p>
<p>I set FILE_EXT to &#8220;wpx&#8221;, which stands for WordPy xml, at the beginning of the WordPy.py file near the top:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">FILE_EXT</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;</span><span class="hl-string">wpx</span><span class="hl-quotes">&quot;</span></pre></div></div>
<p>Another helper function that I added is the set_post_text function:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">set_post_text</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">text</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Simple Helper function that sets the text
	in the text View.
	@param text - The text that will be put into
	the text view.
	</span><span class="hl-quotes">&quot;&quot;&quot;
	</span><span class="hl-comment">#select all of the text
	</span><span class="hl-identifier">start</span><span class="hl-default">, </span><span class="hl-identifier">end</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">txtBuffer</span><span class="hl-default">.</span><span class="hl-identifier">get_bounds</span><span class="hl-brackets">()
	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">txtBuffer</span><span class="hl-default">.</span><span class="hl-identifier">select_range</span><span class="hl-brackets">(</span><span class="hl-identifier">end</span><span class="hl-code">,</span><span class="hl-identifier">start</span><span class="hl-brackets">)
	</span><span class="hl-comment">#insert over the selection i.e. replace all the text
	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">insert_text</span><span class="hl-brackets">(</span><span class="hl-identifier">text</span><span class="hl-brackets">)
	</span><span class="hl-comment">#put the selection at the end.
	</span><span class="hl-identifier">start</span><span class="hl-default">, </span><span class="hl-identifier">end</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">txtBuffer</span><span class="hl-default">.</span><span class="hl-identifier">get_bounds</span><span class="hl-brackets">()
	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">txtBuffer</span><span class="hl-default">.</span><span class="hl-identifier">select_range</span><span class="hl-brackets">(</span><span class="hl-identifier">end</span><span class="hl-code">,</span><span class="hl-identifier">end</span><span class="hl-brackets">)</span></pre></div></div>
<p>It&#8217;s a simple helper function that sets the post text.  It does this by selecting all of the text in the gtk.TextView and then calls the insert_text() function (detailed in the  previous tutorial) which will overwrite what is selected in the gtk.TextView (in this case everything) with the text that it is passed.  After that we simply move the cursor caret to the end of the text.</p>
<h3>Saving the post</h3>
<p>Now that we have all of the base code in place we can start work on actually saving our file to xml, to do that we will use the <a href="http://docs.python.org/lib/module-xml.dom.minidom.html">xml.dom.minidom</a> module.  The reason that I decided to use the xml.dom.minidom object as opposed to the xml.dom object is because the:</p>
<blockquote><p>xml.dom.minidom is a light-weight implementation of the Document Object Model interface. It is intended to be simpler than the full DOM and also significantly smaller.</p></blockquote>
<p>This is perfect for us since we for saving and loading we do not need to perform any exceedingly difficult xml tasks.</p>
<p>The first function we are going to implement is the on_file_save() function:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">on_file_save</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">This function saves the current post as an XML file</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-comment"># Let the user browse for the save location and name
	</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">xml_file</span><span class="hl-code"> == </span><span class="hl-reserved">None</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">xml_file</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">file_browse</span><span class="hl-brackets">(</span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">FILE_CHOOSER_ACTION_SAVE</span><span class="hl-brackets">)
	</span><span class="hl-comment">#If we have a xml_file
	</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">xml_save_to_file</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">))</span><span class="hl-default">:
			</span><span class="hl-comment">#Allright it all worked! Set the Title
			</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">set_window_title_from_file</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)</span></pre></div></div>
<p>This function is pretty simple since it relies on many other functions, this was done so that a lot of the code could be re-used by the on_file_save_as() function. The first thing we do is check to see if self.xml_name has been set, if it hasn&#8217;t we pop up a save dialog and let the user select the location where their file will be saved.  Then if they chose a filename rather then cancelling we will actually start saving our data to xml.</p>
<p>The two main functions we use to accomplish this are xml_save_to_file() and set_window_title_file().  set_window_title_file() is a very simple function that sets the main windows title based upon a file path:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">set_window_title_from_file</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Set the windows title, take it from xml_file.
	@param xml_file - string - The xml file name that we will
	base the window title off of
	</span><span class="hl-quotes">&quot;&quot;&quot;
	</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">main_window</span><span class="hl-default">.</span><span class="hl-identifier">set_title</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">WordPy - %s</span><span class="hl-quotes">&quot;</span><span class="hl-code">
			% </span><span class="hl-brackets">(</span><span class="hl-identifier">os</span><span class="hl-code">.</span><span class="hl-identifier">path</span><span class="hl-code">.</span><span class="hl-identifier">basename</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)))
	</span><span class="hl-reserved">else</span><span class="hl-default">:
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">main_window</span><span class="hl-default">.</span><span class="hl-identifier">set_title</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">WordPy - Untitled</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span></pre></div></div>
<p>The more complicated function is the xml_save_to_file() function:</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">xml_save_to_file</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Save the current post to xml_file
	@param xml_file - string - path to file that
	we will save the xml to.
	@returns boolean - True success. False failure
	</span><span class="hl-quotes">&quot;&quot;&quot;
	</span><span class="hl-comment">#Init return value
	</span><span class="hl-identifier">success</span><span class="hl-default"> = </span><span class="hl-reserved">False

	</span><span class="hl-comment">#Get the available DOM Implementation
	</span><span class="hl-identifier">impl</span><span class="hl-default"> = </span><span class="hl-identifier">minidom</span><span class="hl-default">.</span><span class="hl-identifier">getDOMImplementation</span><span class="hl-brackets">()
	</span><span class="hl-comment">#Create the document, with wordpy as to base node
	</span><span class="hl-identifier">xml_document</span><span class="hl-default"> = </span><span class="hl-identifier">impl</span><span class="hl-default">.</span><span class="hl-identifier">createDocument</span><span class="hl-brackets">(</span><span class="hl-reserved">None</span><span class="hl-code">, </span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">MAIN_TAG</span><span class="hl-brackets">]</span><span class="hl-code">, </span><span class="hl-reserved">None</span><span class="hl-brackets">)
	</span><span class="hl-comment">#Save the post settings into the xml
	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">xml_save</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_document</span><span class="hl-brackets">)
	</span><span class="hl-comment">#Save the Blog settings into the XML
	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">BlogSettings</span><span class="hl-default">.</span><span class="hl-identifier">xml_save</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_document</span><span class="hl-brackets">)
	</span><span class="hl-comment">#Now actually try to save the file
	</span><span class="hl-reserved">try</span><span class="hl-default">:
		</span><span class="hl-identifier">save_file</span><span class="hl-default"> = </span><span class="hl-builtin">open</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">w</span><span class="hl-quotes">'</span><span class="hl-brackets">)
		</span><span class="hl-comment">#write the xml document to disc
		</span><span class="hl-identifier">xml_document</span><span class="hl-default">.</span><span class="hl-identifier">documentElement</span><span class="hl-default">.</span><span class="hl-identifier">writexml</span><span class="hl-brackets">(</span><span class="hl-identifier">save_file</span><span class="hl-brackets">)
		</span><span class="hl-identifier">save_file</span><span class="hl-default">.</span><span class="hl-identifier">close</span><span class="hl-brackets">()
	</span><span class="hl-reserved">except IOError</span><span class="hl-default">, </span><span class="hl-brackets">(</span><span class="hl-identifier">errno</span><span class="hl-code">, </span><span class="hl-identifier">strerror</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">show_error_dlg</span><span class="hl-brackets">(
			</span><span class="hl-quotes">&quot;</span><span class="hl-string">Error saving post(%s): %s</span><span class="hl-quotes">&quot;</span><span class="hl-code"> % </span><span class="hl-brackets">(</span><span class="hl-identifier">errno</span><span class="hl-code">, </span><span class="hl-identifier">strerror</span><span class="hl-brackets">))
	</span><span class="hl-reserved">else</span><span class="hl-default">:
		</span><span class="hl-comment">#Allright it all worked! Set the return value
		</span><span class="hl-identifier">success</span><span class="hl-default"> = </span><span class="hl-reserved">True

	return </span><span class="hl-identifier">success</span></pre></div></div>
<p>The code is a bit complicated so I will take a little bit of time trying to explain each part in it.  The first thing that we do (after initializing the return value) is call minidom.GetDomImplementation() to get a suitable DOM implementation.  You can read more about the Document Object Model in the python documentation <a href="http://docs.python.org/lib/module-xml.dom.html">here</a>.  We then use that DOM implementation to create our xml document using self._xml_tags[MAIN_TAG] as the main tag for our xml document.  Basically this creates:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre>&lt;WordPy&gt;&lt;/WordPy&gt;</pre></div></div>
<p>Then we call two functions self.xml_save() and self.BlogSettings.xml_save() which are functions that will actually save our data into the xml document.  Then we try to open our self.xml_file and write the xml document into that file using the writexml function:</p>
<blockquote><p><strong>writexml(  	writer[,indent=""[,addindent=""[,newl=""]]])</strong><br />
Write XML to the writer object. The writer should have a write() method which matches that of the file object interface. The indent parameter is the indentation of the current node. The addindent parameter is the incremental indentation to use for subnodes of the current one. The newl parameter specifies the string to use to terminate newlines.</p></blockquote>
<p>After that we simply set the windows title based on self.xml_file so that the user knows which file they are currently working with.</p>
<p>The next function to look at is the WordPy.xml_save() function which actually looks more complicated then it really is:</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">xml_save</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">xml_document</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Save the current blog post to an xml document.
	@param xml_document - xml.dom.minidom.Document object -
	The xml document that we will save the post to.</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-comment">#First create the &quot;post&quot; xml element
	</span><span class="hl-identifier">post_element</span><span class="hl-default"> = </span><span class="hl-identifier">xml_document</span><span class="hl-default">.</span><span class="hl-identifier">createElement</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">POST_TAG</span><span class="hl-brackets">])  </span><span class="hl-comment"># creates &lt;post&gt;&lt;/post&gt;
	#Title
	</span><span class="hl-identifier">title</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">enTitle</span><span class="hl-default">.</span><span class="hl-identifier">get_text</span><span class="hl-brackets">()
	</span><span class="hl-comment">#Text
	</span><span class="hl-identifier">start</span><span class="hl-default">, </span><span class="hl-identifier">end</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">txtBuffer</span><span class="hl-default">.</span><span class="hl-identifier">get_bounds</span><span class="hl-brackets">()
	</span><span class="hl-identifier">text</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">txtBuffer</span><span class="hl-default">.</span><span class="hl-identifier">get_text</span><span class="hl-brackets">(</span><span class="hl-identifier">start</span><span class="hl-code">, </span><span class="hl-identifier">end</span><span class="hl-brackets">)
	</span><span class="hl-comment"># creates &lt;title&gt;&lt;/title&gt;
	</span><span class="hl-identifier">title_element</span><span class="hl-default"> = </span><span class="hl-identifier">xml_document</span><span class="hl-default">.</span><span class="hl-identifier">createElement</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">TITLE_TAG</span><span class="hl-brackets">])
	</span><span class="hl-comment">#Create &lt;title&gt;title text&lt;/title&gt;
	</span><span class="hl-identifier">title_element</span><span class="hl-default">.</span><span class="hl-identifier">appendChild</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_document</span><span class="hl-code">.</span><span class="hl-identifier">createTextNode</span><span class="hl-brackets">(</span><span class="hl-identifier">title</span><span class="hl-brackets">))
	</span><span class="hl-comment"># creates &lt;text&gt;&lt;/text&gt;
	</span><span class="hl-identifier">text_element</span><span class="hl-default"> = </span><span class="hl-identifier">xml_document</span><span class="hl-default">.</span><span class="hl-identifier">createElement</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">TEXT_TAG</span><span class="hl-brackets">])
	</span><span class="hl-comment"># creates &lt;text&gt;text&lt;/text&gt;
	</span><span class="hl-identifier">text_element</span><span class="hl-default">.</span><span class="hl-identifier">appendChild</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_document</span><span class="hl-code">.</span><span class="hl-identifier">createTextNode</span><span class="hl-brackets">(</span><span class="hl-identifier">text</span><span class="hl-brackets">))
	</span><span class="hl-comment">#Now create &lt;post&gt;&lt;title&gt;title text&lt;/title&gt;&lt;text&gt;text&lt;/text&gt;&lt;/post&gt;
	</span><span class="hl-identifier">post_element</span><span class="hl-default">.</span><span class="hl-identifier">appendChild</span><span class="hl-brackets">(</span><span class="hl-identifier">title_element</span><span class="hl-brackets">)
	</span><span class="hl-identifier">post_element</span><span class="hl-default">.</span><span class="hl-identifier">appendChild</span><span class="hl-brackets">(</span><span class="hl-identifier">text_element</span><span class="hl-brackets">)
	</span><span class="hl-comment">#Now add to the xml docuemnt
	</span><span class="hl-identifier">xml_document</span><span class="hl-default">.</span><span class="hl-identifier">documentElement</span><span class="hl-default">.</span><span class="hl-identifier">appendChild</span><span class="hl-brackets">(</span><span class="hl-identifier">post_element</span><span class="hl-brackets">)</span></pre></div></div>
<p>Basically it&#8217;s quite simple, we call  xml_document.createElement() to create an xml element (see <a href="http://docs.python.org/lib/dom-document-objects.html">this page</a> for more information on functions available to our Document object.)  Then if we want we create a text node (and xml node that contains a text string) using xml_document.createTextNode() and add that to our newly created xml element.</p>
<p>So the first thing we do is create the post element, and then we create the title and text elements and add those to the post element.  Then we add the post element to the root of our xml document using documentElement which always represents the root element of our xml document.  It&#8217;s really quite simple, hopefully the comments in the code will help to explain each basic step.</p>
<p>The other xml_save function we have is the WordPressBlogSettings.xml_save() function which is very similar to the other xml_save() function:</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">xml_save</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">xml_document</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Save the current blog post to an xml document.
	@param xml_document - xml.dom.minidom.Document object -
	The xml document that we will save the post to.</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-comment">#First create the &quot;settings&quot; xml element
	</span><span class="hl-identifier">settings_element</span><span class="hl-default"> = </span><span class="hl-identifier">xml_document</span><span class="hl-default">.</span><span class="hl-identifier">createElement</span><span class="hl-brackets">(</span><span class="hl-identifier">WordPy</span><span class="hl-code">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">SETTINGS_TAG</span><span class="hl-brackets">])
	</span><span class="hl-comment">#Creates &lt;url&gt;&lt;/url&gt;
	</span><span class="hl-identifier">URL_element</span><span class="hl-default"> = </span><span class="hl-identifier">xml_document</span><span class="hl-default">.</span><span class="hl-identifier">createElement</span><span class="hl-brackets">(</span><span class="hl-identifier">WordPy</span><span class="hl-code">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">URL_TAG</span><span class="hl-brackets">])
	</span><span class="hl-comment">#Create &lt;url&gt;URL&lt;/url&gt;
	</span><span class="hl-identifier">URL_element</span><span class="hl-default">.</span><span class="hl-identifier">appendChild</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_document</span><span class="hl-code">.</span><span class="hl-identifier">createTextNode</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">URL</span><span class="hl-brackets">))
	</span><span class="hl-comment">#Creates &lt;username&gt;&lt;/username&gt;
	</span><span class="hl-identifier">username_element</span><span class="hl-default"> = </span><span class="hl-identifier">xml_document</span><span class="hl-default">.</span><span class="hl-identifier">createElement</span><span class="hl-brackets">(</span><span class="hl-identifier">WordPy</span><span class="hl-code">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">USERNAME_TAG</span><span class="hl-brackets">])
	</span><span class="hl-comment">#Creates &lt;username&gt;Username&lt;/username&gt;
	</span><span class="hl-identifier">username_element</span><span class="hl-default">.</span><span class="hl-identifier">appendChild</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_document</span><span class="hl-code">.</span><span class="hl-identifier">createTextNode</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">Username</span><span class="hl-brackets">))
	</span><span class="hl-comment">#Creates &lt;password&gt;&lt;/password&gt;
	</span><span class="hl-identifier">password_element</span><span class="hl-default"> = </span><span class="hl-identifier">xml_document</span><span class="hl-default">.</span><span class="hl-identifier">createElement</span><span class="hl-brackets">(</span><span class="hl-identifier">WordPy</span><span class="hl-code">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">PASSWORD_TAG</span><span class="hl-brackets">])
	</span><span class="hl-comment">#Creates &lt;password&gt;Password&lt;/password&gt;
	</span><span class="hl-identifier">password_element</span><span class="hl-default">.</span><span class="hl-identifier">appendChild</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_document</span><span class="hl-code">.</span><span class="hl-identifier">createTextNode</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">Password</span><span class="hl-brackets">))
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Now create:
	&lt;post&gt;
		&lt;url&gt;URL&lt;/url&gt;
		&lt;username&gt;Username&lt;/username&gt;
		&lt;password&gt;Password&lt;/password&gt;
	&lt;/post&gt;
	</span><span class="hl-quotes">&quot;&quot;&quot;
	</span><span class="hl-identifier">settings_element</span><span class="hl-default">.</span><span class="hl-identifier">appendChild</span><span class="hl-brackets">(</span><span class="hl-identifier">URL_element</span><span class="hl-brackets">)
	</span><span class="hl-identifier">settings_element</span><span class="hl-default">.</span><span class="hl-identifier">appendChild</span><span class="hl-brackets">(</span><span class="hl-identifier">username_element</span><span class="hl-brackets">)
	</span><span class="hl-identifier">settings_element</span><span class="hl-default">.</span><span class="hl-identifier">appendChild</span><span class="hl-brackets">(</span><span class="hl-identifier">password_element</span><span class="hl-brackets">)
	</span><span class="hl-comment">#Now add to the xml docuemnt
	</span><span class="hl-identifier">xml_document</span><span class="hl-default">.</span><span class="hl-identifier">documentElement</span><span class="hl-default">.</span><span class="hl-identifier">appendChild</span><span class="hl-brackets">(</span><span class="hl-identifier">settings_element</span><span class="hl-brackets">)</span></pre></div></div>
<p>After all this is set and done we end up with an xml file that looks similar to this although not spaced as nicely:</p>
<pre>
<div class="hl-surround" ><div class="hl-main"><pre>&lt;wordpy&gt;
	&lt;post&gt;
		&lt;title&gt;My Blog Post&lt;/title&gt;
		&lt;text&gt;Here is my text&lt;/text&gt;
	&lt;/post&gt;
	&lt;settings&gt;
		&lt;url&gt;	http://www.myblog.com/wordpress/xmlrpc.php&lt;/url&gt;
		&lt;username&gt;user&lt;/username&gt;
		&lt;password&gt;password&lt;/password&gt;
	&lt;/settings&gt;
&lt;/wordpy&gt;</pre></div></div>
</pre>
<p>Now that you see how we can save a file in response to the File | Save menu command you can probably imagine how we will respond to the File | Save As command:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">on_file_save_as</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Let the user save the current file to a new location.</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-identifier">xml_file</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;</span><span class="hl-string">Untitled</span><span class="hl-quotes">&quot;
	</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">xml_file</span><span class="hl-code"> != </span><span class="hl-reserved">None</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">xml_file</span><span class="hl-default"> = </span><span class="hl-identifier">os</span><span class="hl-default">.</span><span class="hl-identifier">path</span><span class="hl-default">.</span><span class="hl-identifier">basename</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)

	</span><span class="hl-identifier">xml_file</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">file_browse</span><span class="hl-brackets">(</span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">FILE_CHOOSER_ACTION_SAVE</span><span class="hl-code">, </span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)
	</span><span class="hl-comment">#If we have a xml_file
	</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">xml_save_to_file</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">))</span><span class="hl-default">:
			</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Allright it all worked! save the current file and
			set the title.</span><span class="hl-quotes">&quot;&quot;&quot;
			</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">xml_file</span><span class="hl-default"> = </span><span class="hl-identifier">xml_file
			self</span><span class="hl-default">.</span><span class="hl-identifier">set_window_title_from_file</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)</span></pre></div></div>
<p>You&#8217;ll notice that it&#8217;s very similar to the on_file_save() function except that we always browse for a file and we pass the name of the current file (if it exists) to the file_browse() function so that the use has a starting point for their save as action.</p>
<p>So that&#8217;s it for saving the next step is opening a saved file.</p>
<h3>Opening an save file</h3>
<p>Opening one of our xml files is very similar to saving them except instead of creating the xml document and each node, we need to loop through an existing document and load each node into our specific variables.  The first thing that we need to do is respond to the File | Open menu command:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">on_file_open</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:

	</span><span class="hl-identifier">xml_file</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">file_browse</span><span class="hl-brackets">(</span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">FILE_CHOOSER_ACTION_OPEN</span><span class="hl-brackets">)
	</span><span class="hl-comment">#If we have a xml_file
	</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">xml_load_from_file</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">))</span><span class="hl-default">:
			</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Allright it all worked! save the current file and
			set the title.</span><span class="hl-quotes">&quot;&quot;&quot;
			</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">xml_file</span><span class="hl-default"> = </span><span class="hl-identifier">xml_file
			self</span><span class="hl-default">.</span><span class="hl-identifier">set_window_title_from_file</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)</span></pre></div></div>
<p>Pretty standard stuff, we let the user browse for an xml file, and if they don&#8217;t cancel the operation we then load the xml file.  If that is successful we save the path to the xml file and then set the windows title.  Not much happening here as most of the work is done in xml_load_from_file():</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">xml_load_from_file</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Load a post from an xml file
	@param xml_file - string - path to file that
	we will load.
	@returns boolean - True success. False failure
	</span><span class="hl-quotes">&quot;&quot;&quot;
	</span><span class="hl-comment">#Init return value
	</span><span class="hl-identifier">success</span><span class="hl-default"> = </span><span class="hl-reserved">False

	</span><span class="hl-comment">#Load the xml_file to a document
	</span><span class="hl-reserved">try</span><span class="hl-default">:
		</span><span class="hl-identifier">xml_document</span><span class="hl-default"> = </span><span class="hl-identifier">minidom</span><span class="hl-default">.</span><span class="hl-identifier">parse</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)
		</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">xml_document</span><span class="hl-brackets">)</span><span class="hl-default">:
			</span><span class="hl-identifier">success</span><span class="hl-default"> = </span><span class="hl-brackets">((</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">xml_load</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_document</span><span class="hl-brackets">))
					</span><span class="hl-identifier">and </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">BlogSettings</span><span class="hl-code">.</span><span class="hl-identifier">xml_load</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_document</span><span class="hl-brackets">)))
	</span><span class="hl-reserved">except IOError</span><span class="hl-default">, </span><span class="hl-brackets">(</span><span class="hl-identifier">errno</span><span class="hl-code">, </span><span class="hl-identifier">strerror</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">show_error_dlg</span><span class="hl-brackets">(
			</span><span class="hl-quotes">&quot;</span><span class="hl-string">Error loading post file(%s): %s</span><span class="hl-quotes">&quot;</span><span class="hl-code"> % </span><span class="hl-brackets">(</span><span class="hl-identifier">errno</span><span class="hl-code">, </span><span class="hl-identifier">strerror</span><span class="hl-brackets">))
	</span><span class="hl-reserved">except</span><span class="hl-default">:
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">show_error_dlg</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Error loading post file.</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
	</span><span class="hl-reserved">return </span><span class="hl-identifier">success</span></pre></div></div>
<p>In this function we create our xml.minidom.Document object by telling the minidom mdule to parse the xml file that was passed to the function.  If that does not succeed we catch the appropriate exceptions and show our error dialog top the user.  If the parsing the file does succeed we load the post and the blog settings from the XML document. WordPy.xml_load() loads the post from the xml document:</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">xml_load</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">xml_document</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Load the current blog post from an xml document.
	@param xml_document - xml.dom.minidom.Document object -
	The xml document that we will load the post from.
	@returns boolean True - success.  False - Failure.</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-identifier">title_loaded</span><span class="hl-default"> = </span><span class="hl-reserved">False
	</span><span class="hl-identifier">text_loaded</span><span class="hl-default"> = </span><span class="hl-reserved">False

	</span><span class="hl-comment">#Loop through all child nodes of the root.
	</span><span class="hl-reserved">for </span><span class="hl-identifier">node </span><span class="hl-reserved">in </span><span class="hl-identifier">xml_document</span><span class="hl-default">.</span><span class="hl-identifier">documentElement</span><span class="hl-default">.</span><span class="hl-identifier">childNodes</span><span class="hl-default">:
		</span><span class="hl-comment">#We are looking for the post Node
		</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">node</span><span class="hl-code">.</span><span class="hl-identifier">nodeName</span><span class="hl-code"> == </span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">POST_TAG</span><span class="hl-brackets">])</span><span class="hl-default">:
			</span><span class="hl-comment"># Now loop through the post nodes children
			</span><span class="hl-reserved">for </span><span class="hl-identifier">item_node </span><span class="hl-reserved">in </span><span class="hl-identifier">node</span><span class="hl-default">.</span><span class="hl-identifier">childNodes</span><span class="hl-default">:
				</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">item_node</span><span class="hl-code">.</span><span class="hl-identifier">nodeName</span><span class="hl-code"> == </span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">TITLE_TAG</span><span class="hl-brackets">])</span><span class="hl-default">:
					</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Set the title, the firstChild in this case is
					the actual title text that we saved.</span><span class="hl-quotes">&quot;&quot;&quot;

					</span><span class="hl-comment">#Make sure it's not a blank string
					</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">item_node</span><span class="hl-code">.</span><span class="hl-identifier">firstChild</span><span class="hl-brackets">)</span><span class="hl-default">:
						</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">enTitle</span><span class="hl-default">.</span><span class="hl-identifier">set_text</span><span class="hl-brackets">(</span><span class="hl-identifier">item_node</span><span class="hl-code">.</span><span class="hl-identifier">firstChild</span><span class="hl-code">.</span><span class="hl-identifier">nodeValue</span><span class="hl-brackets">)
					</span><span class="hl-reserved">else</span><span class="hl-default">:
						</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">enTitle</span><span class="hl-default">.</span><span class="hl-identifier">set_text</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;&quot;</span><span class="hl-brackets">)
					</span><span class="hl-identifier">title_loaded</span><span class="hl-default"> = </span><span class="hl-reserved">True
				</span><span class="hl-identifier">elif </span><span class="hl-brackets">(</span><span class="hl-identifier">item_node</span><span class="hl-code">.</span><span class="hl-identifier">nodeName</span><span class="hl-code"> == </span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">TEXT_TAG</span><span class="hl-brackets">])</span><span class="hl-default">:
					</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Set the text, the firstChild in this case is
					the actual text that we saved.</span><span class="hl-quotes">&quot;&quot;&quot;
					</span><span class="hl-comment">#Make sure it's not a blank string
					</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">item_node</span><span class="hl-code">.</span><span class="hl-identifier">firstChild</span><span class="hl-brackets">)</span><span class="hl-default">:
						</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">set_post_text</span><span class="hl-brackets">(</span><span class="hl-identifier">item_node</span><span class="hl-code">.</span><span class="hl-identifier">firstChild</span><span class="hl-code">.</span><span class="hl-identifier">nodeValue</span><span class="hl-brackets">)
					</span><span class="hl-reserved">else</span><span class="hl-default">:
						</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">set_post_text</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;&quot;</span><span class="hl-brackets">)
					</span><span class="hl-identifier">text_loaded</span><span class="hl-default"> = </span><span class="hl-reserved">True
			</span><span class="hl-comment">#Break out of the topmost for loop
			</span><span class="hl-reserved">break

	</span><span class="hl-identifier">return </span><span class="hl-brackets">(</span><span class="hl-identifier">title_loaded </span><span class="hl-reserved">and </span><span class="hl-identifier">text_loaded</span><span class="hl-brackets">)</span></pre></div></div>
<p>Basically what we do when loading our values is loop through the all of the child nodes of the root node looking for nodes that match whatever criteria we are looking for.  So in the xml example file:</p>
<pre>
<div class="hl-surround" ><div class="hl-main"><pre>&lt;wordpy&gt;
	&lt;post&gt;
		&lt;title&gt;My Blog Post&lt;/title&gt;
		&lt;text&gt;Here is my text&lt;/text&gt;
	&lt;/post&gt;
	&lt;settings&gt;
		&lt;url&gt;http://www.myblog.com/wordpress/xmlrpc.php&lt;/url&gt;
		&lt;username&gt;user&lt;/username&gt;
		&lt;password&gt;password&lt;/password&gt;
	&lt;/settings&gt;
&lt;/wordpy&gt;</pre></div></div>
</pre>
<p>The root node or the documentElement item, is the &lt;wordpy&gt; element.  So if we were to loop through its child nodes the first node that we would encounter would be the &lt;post&gt; node and then next node would be the &lt;settings&gt; node.  Then if we looped through he &lt;post&gt; elements children we would encounter the &lt;title&gt; and the &lt;text&gt; node.  The sole child node of either of those two nodes happens to be their actual text.</p>
<p>After explaining that it should be pretty obvious what is happening in the WordPy.xml_load() function.  Basically we loop through all the children of the root node looking for the &lt;post&gt; node.  Once we find it we then loop through all of the  &lt;post&gt; node&#8217;s children looking for the &lt;title&gt; and the &lt;text&gt; node.  When we encounter either the &lt;title&gt; node or the &lt;text&gt; node we get the the nodeValue of the firstChild, if it exists.  The firstChild of either of those two nodes happens to be the actual text node that we want to load.  The nodeValue of the text nodes is their actual text.  If firstChild did not exist it means that a blank string was saved into the text file.</p>
<p>For me the xml metaphoer built up by the xml.dom slightly of falls apart when then actual text is considered another node, but the implementation is simple and works well enough so I shouldn&#8217;t complain. (Plus there is probably a very good reason for this)</p>
<p>We also set boolean values to True to make sure that we know whether or not all of the proper elements were loaded.  This is an optional step as you might not care if everything was loaded properly..</p>
<p>The BlogSettings.xml_load() function does the exact same thing except that it looks for different nodes, as a result I will show it but I won&#8217;t bother explaining it.</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">xml_load</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">xml_document</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Load the current blog post from an xml document.
	@param xml_document - xml.dom.minidom.Document object -
	The xml document that we will load the post from.
	@returns boolean True - success.  False - Failure.</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-identifier">URL_loaded</span><span class="hl-default"> = </span><span class="hl-reserved">False
	</span><span class="hl-identifier">username_loaded</span><span class="hl-default"> = </span><span class="hl-reserved">False
	</span><span class="hl-identifier">password_loaded</span><span class="hl-default"> = </span><span class="hl-reserved">False

	</span><span class="hl-comment">#Loop through all child nodes of the root.
	</span><span class="hl-reserved">for </span><span class="hl-identifier">node </span><span class="hl-reserved">in </span><span class="hl-identifier">xml_document</span><span class="hl-default">.</span><span class="hl-identifier">documentElement</span><span class="hl-default">.</span><span class="hl-identifier">childNodes</span><span class="hl-default">:
		</span><span class="hl-comment">#We are looking for the post Node
		</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">node</span><span class="hl-code">.</span><span class="hl-identifier">nodeName</span><span class="hl-code"> == </span><span class="hl-identifier">WordPy</span><span class="hl-code">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">SETTINGS_TAG</span><span class="hl-brackets">])</span><span class="hl-default">:
			</span><span class="hl-comment"># Now loop through the post nodes children
			</span><span class="hl-reserved">for </span><span class="hl-identifier">item_node </span><span class="hl-reserved">in </span><span class="hl-identifier">node</span><span class="hl-default">.</span><span class="hl-identifier">childNodes</span><span class="hl-default">:
				</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">item_node</span><span class="hl-code">.</span><span class="hl-identifier">nodeName</span><span class="hl-code"> == </span><span class="hl-identifier">WordPy</span><span class="hl-code">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">URL_TAG</span><span class="hl-brackets">])</span><span class="hl-default">:
					</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Set the URL</span><span class="hl-quotes">&quot;&quot;&quot;
					</span><span class="hl-comment">#Make sure it's not a blank string
					</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">item_node</span><span class="hl-code">.</span><span class="hl-identifier">firstChild</span><span class="hl-brackets">)</span><span class="hl-default">:
						</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">URL</span><span class="hl-default"> = </span><span class="hl-identifier">item_node</span><span class="hl-default">.</span><span class="hl-identifier">firstChild</span><span class="hl-default">.</span><span class="hl-identifier">nodeValue
					</span><span class="hl-reserved">else</span><span class="hl-default">:
						</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">URL</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;&quot;
					</span><span class="hl-identifier">URL_loaded</span><span class="hl-default"> = </span><span class="hl-reserved">True
				</span><span class="hl-identifier">elif </span><span class="hl-brackets">(</span><span class="hl-identifier">item_node</span><span class="hl-code">.</span><span class="hl-identifier">nodeName</span><span class="hl-code"> == </span><span class="hl-identifier">WordPy</span><span class="hl-code">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">USERNAME_TAG</span><span class="hl-brackets">])</span><span class="hl-default">:
					</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Set the username</span><span class="hl-quotes">&quot;&quot;&quot;
					</span><span class="hl-comment">#Make sure it's not a blank string
					</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">item_node</span><span class="hl-code">.</span><span class="hl-identifier">firstChild</span><span class="hl-brackets">)</span><span class="hl-default">:
						</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">Username</span><span class="hl-default"> = </span><span class="hl-identifier">item_node</span><span class="hl-default">.</span><span class="hl-identifier">firstChild</span><span class="hl-default">.</span><span class="hl-identifier">nodeValue
					</span><span class="hl-reserved">else</span><span class="hl-default">:
						</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">Username</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;&quot;
					</span><span class="hl-identifier">username_loaded</span><span class="hl-default"> = </span><span class="hl-reserved">True
				</span><span class="hl-identifier">elif </span><span class="hl-brackets">(</span><span class="hl-identifier">item_node</span><span class="hl-code">.</span><span class="hl-identifier">nodeName</span><span class="hl-code"> == </span><span class="hl-identifier">WordPy</span><span class="hl-code">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">PASSWORD_TAG</span><span class="hl-brackets">])</span><span class="hl-default">:
					</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Set the pasword</span><span class="hl-quotes">&quot;&quot;&quot;
					</span><span class="hl-comment">#Make sure it's not a blank string
					</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">item_node</span><span class="hl-code">.</span><span class="hl-identifier">firstChild</span><span class="hl-brackets">)</span><span class="hl-default">:
						</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">Password</span><span class="hl-default"> = </span><span class="hl-identifier">item_node</span><span class="hl-default">.</span><span class="hl-identifier">firstChild</span><span class="hl-default">.</span><span class="hl-identifier">nodeValue
					</span><span class="hl-reserved">else</span><span class="hl-default">:
						</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">Password</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;&quot;
					</span><span class="hl-identifier">password_loaded</span><span class="hl-default"> = </span><span class="hl-reserved">True
		</span><span class="hl-comment">#Break out of the topmost for loop
		</span><span class="hl-reserved">break

	</span><span class="hl-identifier">return </span><span class="hl-brackets">(</span><span class="hl-identifier">URL_loaded </span><span class="hl-reserved">and </span><span class="hl-identifier">username_loaded </span><span class="hl-reserved">and </span><span class="hl-identifier">password_loaded</span><span class="hl-brackets">)</span></pre></div></div>
<h3>Starting a new file</h3>
<p>All that&#8217;s left now is to handle the File | New menu command:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">on_file_new</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">enTitle</span><span class="hl-default">.</span><span class="hl-identifier">set_text</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;&quot;</span><span class="hl-brackets">)
	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">set_post_text</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;&quot;</span><span class="hl-brackets">)
	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">xml_file</span><span class="hl-default"> = </span><span class="hl-reserved">None
	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">set_window_title_from_file</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)</span></pre></div></div>
<p>It doesn&#8217;t really do much except blank out the title and text, make it so that there is no xml file, and sets the window title to &#8220;Wordpy – Untitled&#8221; (which is what set_window_title will do when passed None as the xml file.)</p>
<p>Since this is a good way to initialize WordPy I call it in the __init__ function:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-comment">#initialize to new
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_file_new</span><span class="hl-brackets">(</span><span class="hl-reserved">None</span><span class="hl-brackets">)</span></pre></div></div>
<h2>The End</h2>
<p>You can download the complete code for this tutorial <a href="http://www.learningpython.com/sources/WordPy_0_2.tar.gz">here</a>.</p>
<p>Well that&#8217;s it for this lesson on saving and loading data from an xml file, there are still many more things that need to be done to WordPy, like figuring out what the best way to handle the blog settings are since I&#8217;ve never been happy with the way that they were handled in the previous tutorial.  For example  should they be separate from the post&#8217;s when you save them?  Should there be a list of blog settings?  Should you have to log into your blog first?  I&#8217;m not sure yet but those will be left for another post since this one was simply designed to show one method for saving and loading data from xml files using python.</p>
<p>As always if you have any questions or notice any problems please leave a comment!</p>
<div style="float:right;margin:0px 0px 0px 0px;"><a href="http://www.google.com/reader/link?url=http://www.learningpython.com/2006/10/24/wordpy-02-using-xml-to-save-and-load-data/&title=WordPy 0.2 - Using XML to Save and Load Data&srcTitle=learning python&srcURL=http://www.learningpython.com"target="_blank" rel=""><img border="0" src="http://www.learningpython.com/wp-content/plugins/wp-google-buzz/icon/12.png" style="opacity:1;filter:alpha(opacity=100)" onmouseover="this.style.opacity=0.8;this.filters.alpha.opacity=70" onmouseout="this.style.opacity=1;this.filters.alpha.opacity=100"/> </a></div>]]></content:encoded>
			<wfw:commentRss>http://www.learningpython.com/2006/10/24/wordpy-02-using-xml-to-save-and-load-data/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
	</channel>
</rss>
