<?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>Basil Vandegriend: Professional Software Development &#187; dom4j</title>
	<atom:link href="http://www.basilv.com/psd/blog/tag/dom4j/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.basilv.com/psd</link>
	<description></description>
	<lastBuildDate>Wed, 25 Jan 2012 13:23:47 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Simple XML Parsing using JAXB</title>
		<link>http://www.basilv.com/psd/blog/2008/simple-xml-parsing-using-jaxb</link>
		<comments>http://www.basilv.com/psd/blog/2008/simple-xml-parsing-using-jaxb#comments</comments>
		<pubDate>Mon, 08 Dec 2008 23:12:32 +0000</pubDate>
		<dc:creator>Basil Vandegriend</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[dom4j]]></category>
		<category><![CDATA[JAXB]]></category>
		<category><![CDATA[software development]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://www.basilv.com/psd/?p=210</guid>
		<description><![CDATA[I recently needed to parse a XML file using Java for a utility I was writing. A couple of years ago I used dom4j to parse XML (and wrote an article about it). I figured there had to be a more modern approach, similar to how Hibernate 3.0 can map POJOs (plain old Java objects) [...]]]></description>
			<content:encoded><![CDATA[<p>I recently needed to parse a XML file using Java for a utility I was writing. A couple of years ago I used <a href="http://www.dom4j.org/">dom4j</a> to parse XML (and wrote an <a href="http://www.basilv.com/psd/blog/2006/parsing-and-generating-xml-with-java">article</a> about it). I figured there had to be a more modern approach, similar to how <a href="http://www.hibernate.org/">Hibernate 3.0</a> can map POJOs (plain old Java objects) to relational database tables using <a href="http://www.basilv.com/psd/blog/2008/working-with-java-5-annotations">Java annotations</a>. To my surprise, a brief search on-line turned up nothing. I was sure I had heard of this being done, so I continued searching. I finally found an <a href="http://jvalentino.blogspot.com/2008/07/in-response-to-easiest-java-xml-binding.html">article</a>  with a comment by <a href="http://www.blogger.com/profile/06165108938304365215">zaeffi</a> that finally enlightened me. The answer was to use <a href="https://jaxb.dev.java.net/">JAXB 2.0</a>.</p>
<p>I had already looked at JAXB, but was turned off by the apparent requirement to generate the Java classes from a XML Schema definition of the XML format - I already had my Java POJOs and did not want to be bothered to write a schema definition. It turns out that JAXB does support my use case. The online documentation, unfortunately, seems strongly biased towards web services developers who more than likely do start with a schema definition, and possibly even have tooling that hides the use of JAXB entirely. I was also misled by older documentation referring to JAXB version 1, which does not support annotations and generates (from the schema) very ugly code that is difficult to maintain. This was fixed in JAXB version 2, which does support the use of annotations (and incidentally generates much cleaner code).</p>
<p>Using that <a href="http://jvalentino.blogspot.com/2008/07/in-response-to-easiest-java-xml-binding.html">article</a> as inspiration, I wrote a helper class for parsing XML into objects and vice-versa. The code for this helper class is shown below:</p>
<pre class="prettyprint">
// Copyright 2008 by Basil Vandegriend.  All rights reserved.

package com.basilv.examples.jaxb;

import java.io.Reader;
import java.io.Writer;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.*;

import org.w3c.dom.Node;

/**
 * Tools for working with the JAXB (XML Binding) library.
 */
public class XmlBindingTools
{
  /**
   * Parse the XML supplied by the reader into the
   * corresponding tree of Java objects.
   *
   * @param reader Cannot be null. The source of the XML.
   * @param rootElementClass Cannot be null. The type of the
   *        root element.
   * @return the Java object that is the root of the tree,
   *         of type rootElement.
   * @throws JAXBException if an error occurs parsing the
   *         XML.
   */
  @SuppressWarnings("unchecked")
  public static &lt;E extends Object&gt; E parseXML(
    Reader reader, Class&lt;E&gt; rootElementClass)
    throws JAXBException {

    if (rootElementClass == null)
      throw new IllegalArgumentException("rootElementClass is null");
    if (reader == null)
      throw new IllegalArgumentException("reader is null");

    JAXBContext context = JAXBContext.newInstance(rootElementClass);
    Unmarshaller unmarshaller = context.createUnmarshaller();

    CollectingValidationEventHandler handler =
      new CollectingValidationEventHandler();
    unmarshaller.setEventHandler(handler);

    E object = (E) unmarshaller.unmarshal(reader);
    if (!handler.getMessages().isEmpty()) {
      String errorMessage = "XML parse errors:";
      for (String message : handler.getMessages()) {
        errorMessage += "\n" + message;
      }
      throw new JAXBException(errorMessage);
    }

    return object;
  }

  /**
   * Generate XML using the supplied root element as the
   * root of the object tree and write the resulting XML to
   * the specified writer
   *
   * @param rootElement Cannot be null.
   * @param writer Cannot be null.
   * @throws JAXBException
   */
  public static void generateXML(Object rootElement,
    Writer writer) throws JAXBException {

    if (rootElement == null)
      throw new IllegalArgumentException("rootElement is null");
    if (writer == null)
      throw new IllegalArgumentException("writer is null");

    JAXBContext context = JAXBContext.newInstance(rootElement.getClass());
    Marshaller marshaller = context.createMarshaller();
    marshaller.setProperty(
      Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
    marshaller.marshal(rootElement, writer);
  }

  private static class CollectingValidationEventHandler
    implements ValidationEventHandler
  {
    private List&lt;String&gt; messages = new ArrayList&lt;String&gt;();

    public List&lt;String&gt; getMessages() {
      return messages;
    }

    public boolean handleEvent(ValidationEvent event) {
      if (event == null)
        throw new IllegalArgumentException("event is null");

      // calculate the severity prefix and return value
      String severity = null;
      boolean continueParsing = false;
      switch (event.getSeverity()) {
        case ValidationEvent.WARNING:
          severity = "Warning";
          continueParsing = true; // continue after warnings
          break;
        case ValidationEvent.ERROR:
          severity = "Error";
          continueParsing = true; // terminate after errors
          break;
        case ValidationEvent.FATAL_ERROR:
          severity = "Fatal error";
          continueParsing = false; // terminate after fatal errors
          break;
        default:
          assert false : "Unknown severity.";
      }

      String location = getLocationDescription(event);
      String message = severity + " parsing " + location
        + " due to " + event.getMessage();
      messages.add(message);

      return continueParsing;
    }

    private String getLocationDescription(ValidationEvent event) {
      ValidationEventLocator locator = event.getLocator();
      if (locator == null) {
        return "XML with location unavailable";
      }

      StringBuffer msg = new StringBuffer();
      URL url = locator.getURL();
      Object obj = locator.getObject();
      Node node = locator.getNode();
      int line = locator.getLineNumber();

      if (url != null || line != -1) {
        msg.append("line " + line);
        if (url != null) msg.append(" of " + url);
      } else if (obj != null) {
        msg.append(" obj: " + obj.toString());
      } else if (node != null) {
        msg.append(" node: " + node.toString());
      }

      return msg.toString();
    }
  }
}
</pre>
<p>One important refinement I made to the code was to add better error handling. Parser warnings and errors are collected along with location information (such as line numbers) and the caller notified via an exception. This was necessary because the JAXB default error handling simply wrote messages to the console and reported nothing back to the caller. Due to my basic needs, I simply collected these errors and warnings into string messages. If your error-handling requirements are more sophisticated then you can collect the errors and warnings into proper objects that are returned back to the caller, who can then traverse the information and decide how to report it.</p>
<p>The unit test for this helper class is shown below. It includes a utility class with JAXB annotations to map it to XML that the tests use to exercise the functionality of the helper class. The last test exercises (in a trivial way) the additional error-handling functionality.</p>
<pre class="prettyprint">
// Copyright 2008 by Basil Vandegriend.  All rights reserved.

package com.basilv.examples.jaxb;

import static org.junit.Assert.*;

import java.io.StringReader;
import java.io.StringWriter;

import javax.xml.bind.JAXBException;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;

import org.junit.Test;

public class XmlBindingToolsTest
{
  @XmlRootElement(name = "xmltest")
  static class XmlTest
  {
    private String id;

    @XmlAttribute
    public String getId() {
      return id;
    }

    public void setId(String id) {
      this.id = id;
    }

  }

  @Test
  public void parseXml() throws Exception {

    String xml = "&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;\n"
      + "&lt;xmltest id=\"test\"/&gt;";

    StringReader reader = new StringReader(xml);
    XmlTest xmlTest = XmlBindingTools.parseXML(reader,
      XmlTest.class);
    assertNotNull(xmlTest);
    assertEquals("test", xmlTest.getId());
  }

  @Test
  public void generateXml() throws Exception {
    XmlTest xmlTest = new XmlTest();
    xmlTest.setId("test");
    StringWriter writer = new StringWriter();
    XmlBindingTools.generateXML(xmlTest, writer);
    assertEquals(
      "&lt;?xml version=\"1.0\" encoding=\"UTF-8\" "
        + "standalone=\"yes\"?&gt;\n&lt;xmltest id=\"test\"/&gt;\n",
      writer.getBuffer().toString());
  }

  @Test
  public void parseInvalidXml() throws Exception {

    String xml = "&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;\n"
      + "&lt;xmltest id=\"test\"&gt;&lt;fake/&gt;&lt;/xmltest&gt;";

    StringReader reader = new StringReader(xml);
    try {
      XmlBindingTools.parseXML(reader, XmlTest.class);
      fail("Expected Exception");
    } catch (JAXBException e) {
      // Expected case.
    }
  }

}
</pre>
<p>I did encounter some surprises when using JAXB. JAXB imposes a number of coding limitations on the mapped POJOs which are actually quite similar to Hibernate, but not documented as well. So as a general guideline, use Hibernate's restrictions and you will probably do okay. One limitation I encountered involved handling a parent-child relationship between two mapped entities. The parent class will need to have a collection of child entities. The getter method to return the collection must return the actual collection used by the class and not a copy or wrapper: JAXB appears to add children to the parent by calling the add() method on the collection returned by the getter. (See <a href="http://www.basilv.com/psd/blog/2008/exposing-mutable-objects-as-public-properties">this article</a> for why you might want to return a copy of the underlying collection.)</p>
<p>JAXB shares more than just limitations with Hibernate. Many of the mapping capabilities offered by Hibernate have analogues in JAXB. JAXB can map both fields and methods, either of which may be private. JAXB also supports mapping to custom types using the <code>@XmlJavaTypeAdapter</code> annotation. </p>
<p>Despite the limitations and surprises I ran into, I was generally pleased with JAXB. It met my original goal of providing simple parsing of XML into Java POJOs using annotations to specify the mapping. My biggest disappointment with JAXB was the poor documentation. In fact, for all but trivial parsing tasks, I would recommend writing a XML Schema definition and generating the POJOs instead of doing what I did - the documentation just does not support the approach I took.</p>
<p>The source code listed in this article is provided in the <em>Java Examples</em> project which can be downloaded from the <a href="http://www.basilv.com/psd/software">Software</a> page.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.basilv.com/psd/blog/2008/simple-xml-parsing-using-jaxb/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Parsing and Generating XML with Java</title>
		<link>http://www.basilv.com/psd/blog/2006/parsing-and-generating-xml-with-java</link>
		<comments>http://www.basilv.com/psd/blog/2006/parsing-and-generating-xml-with-java#comments</comments>
		<pubDate>Thu, 27 Apr 2006 15:00:06 +0000</pubDate>
		<dc:creator>Basil Vandegriend</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[dom4j]]></category>
		<category><![CDATA[JAXP]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://www.basilv.com/psd/blog/2006/parsing-and-generating-xml-with-java</guid>
		<description><![CDATA[December, 2008 Update: I now recommend using JAXB and annotated Java objects to parse and generate XML. See my article Simple XML Parsing using JAXB for details. I've worked a lot with XML over the years (i.e. for Ant build files), but I've never had to parse or generate XML in Java until recently. There [...]]]></description>
			<content:encoded><![CDATA[<p><strong>December, 2008 Update</strong>: I now recommend using JAXB and annotated Java objects to parse and generate XML. See my article <a href="http://www.basilv.com/psd/blog/2008/simple-xml-parsing-using-jaxb">Simple XML Parsing using JAXB</a> for details.</p>
<p>I've worked a lot with <a href="http://www.w3.org/XML/">XML</a> over the years (i.e. for Ant build files), but I've never had to parse or generate XML in Java until recently. There are many options for working with XML in Java, so I thought I'd share the approach I picked. I'll assume you are already familiar with the basics of XML.</p>
<p>Java has a standard API for XML parsing called JAXP (Java API for XML Processing), which includes two different types of parsers: SAX and DOM. The SAX (Simple API for XML) parser is event-based: as it parses the XML, it generates events  for each type of syntactical element, and the parsing code you write can choose which events to deal with. The DOM (Document Object Model) parser builds a tree structure in memory representing the XML. Since Java 1.4, the JAXP parsers have been included with the JRE, so you can use JAXP without any additional libraries required. The SAX parser is great for working with very large documents that won't fit in memory, while the DOM parser is great when you need to make multiple passes over the document, or need to transform it. The SAX and DOM parsers are actual language-neutral APIs from the W3C, and as such suffer from a few problems. The Java version of these APIs don't always follow normal Java API conventions. Another problem is more of a feature: the APIs can handle any feature of XML, including comments and white space, which makes the API more complicated and low-level, and sometimes leads to non-intuitive behavior.</p>
<p>For example, mixed mode XML where elements are mingled with text requires that each piece of text be contained in its own text node. Consider the xml fragment: &lt;p&gt;Mixed &lt;em&gt;mode&lt;/em&gt; text&lt;/p&gt;. When expressed as a DOM tree, the resulting 'p' node contains three children: a text node containing 'Mixed', an 'em' node which itself contains a text node , and another text node containing 'text'. While mixed mode XML is necessary for cases such as XHTML, it is seldom used in programmatic contexts. Therefore, working with the DOM tree is more painful because of all the additional text nodes.</p>
<p>JAXB (Java Architecture for XML Binding) is another approach to parsing XML which converts the XML document directly to generated Java classes based on a XML Schema. This method is called binding, and it is conceptually similar to object-relational mapping frameworks such as <a href="http://www.hibernate.org/">Hibernate</a>. JAXB generates the Java classes based on the XML Schema, although you can instead provide your own classes mapped via annotations. There are limitations to the binding approach. Requiring an XML schema means that certain types of dynamic parsing cannot be done - i.e. in Ant, you can define new tasks in the ant build XML file which essentially extend the XML schema being used dynamically. Also, the binding strategy used generally places limitations on the types of XML supported - i.e. I don't believe mixed mode is supported. I have heard of open source libraries for XML binding (i.e. <a href="http://www.castor.org/">Castor</a>) and they might avoid some of the limitations of JAXB. But overall, I thought that the binding approach was more complexity than what I needed on my simple project. </p>
<p>There are many open source libraries for working with XML. After looking at some of them, I selected <a href="http://www.dom4j.org/">dom4j</a>. This library is built on top of JAXP but provides a more convenient API, for example using the Java Collections API rather than custom lists. Dom4j allows use of either the SAX or DOM parser internally, depending on your requirements.</p>
<p>To demonstrate the use of dom4j for parsing and generating XML, I'll start with some Java classes representing a maze, which I want to be able to convert to XML or create from XML.</p>
<pre class="prettyprint">
/**
 * The maze is defined to be a certain # of squares wide and high. The
 * coordinate system for squares is that the top left hand corner is (0,0).
 * The maze can contain walls, which follow the grid.
 */
public class Maze
{
  private Dimension size;
  private List<Wall> walls = new ArrayList<Wall>();
  private String description;

  public Maze(int width, int height) {
    size = new Dimension(width, height);
  }

  public Dimension getSize() {
    return size;
  }

  public void addWall(int startX, int startY, int endX, int endY) {
    walls.add(new Wall(startX, startY, endX, endY));
  }

  public List<Wall> getWalls() {
    return walls;
  }

  public String getDescription() {
    return description;
  }

  public void setDescription(String description) {
    this.description = description;
  }
}

public class Wall
{
  private Point start;
  private Point end;

  public Wall(int startX, int startY, int endX, int endY) {
    start = new Point(startX, startY);
    end = new Point(endX, endY);
  }

  public Point getEnd() {
    return end;
  }

  public Point getStart() {
    return start;
  }

  @Override public boolean equals(Object obj) {
    if (!(obj instanceof Wall)) {
      return false;
    }
    Wall other = (Wall) obj;
    return this.start.equals(other.start) &#038;& this.end.equals(other.end);
  }

  @Override public int hashCode() {
    return this.start.hashCode() + 7 * this.end.hashCode();
  }
}
</pre>
<p>I placed the code to generate and parse XML in a single class called MazeXmlConverter. In this class I defined constants for the XML element and attribute names which would be used by both the generation and parsing code. Looking at these constants suggests the structure of the XML document, so I never bothered creating a DTD or XML Schema.</p>
<pre class="prettyprint">
public class MazeXmlConverter
{
  private static final String MAZE_ELEMENT = "maze";
  private static final String HEIGHT_ATTRIBUTE = "height";
  private static final String WIDTH_ATTRIBUTE = "width";
  private static final String WALL_ELEMENT = "wall";
  private static final String START_X_ATTRIBUTE = "startX";
  private static final String START_Y_ATTRIBUTE = "startY";
  private static final String END_X_ATTRIBUTE = "endX";
  private static final String END_Y_ATTRIBUTE = "endY";
}
</pre>
<p>The code to generate XML from a Maze object is quite simple: I create the root document object, then add elements with attributes and/or text as required as I iterate over the Maze.</p>
<pre class="prettyprint">
  public String toXml(Maze maze) {
    Document document = DocumentHelper.createDocument();
    Element root = document.addElement(MAZE_ELEMENT)
      .addAttribute(WIDTH_ATTRIBUTE, Integer.toString(maze.getSize().width))
      .addAttribute(HEIGHT_ATTRIBUTE, Integer.toString(maze.getSize().height))
      .addText(nullToEmpty(maze.getDescription()));

    for (Wall wall : maze.getWalls()) {
      root.addElement(WALL_ELEMENT)
        .addAttribute(START_X_ATTRIBUTE, Integer.toString(wall.getStart().x))
        .addAttribute(START_Y_ATTRIBUTE, Integer.toString(wall.getStart().y))
        .addAttribute(END_X_ATTRIBUTE, Integer.toString(wall.getEnd().x))
        .addAttribute(END_Y_ATTRIBUTE, Integer.toString(wall.getEnd().y));
    }
    return document.asXML();
  }

  private String nullToEmpty(String text) {
    if (text == null) {
      return "";
    } else {
      return text;
    }
  }
}
</pre>
<p>The code to parse XML is a little more complicated. I first parse the XML to create a Document object. While for my project I need to parse XML from a file, I also needed to be able to parse XML from a string for unit testing. Fortunately, dom4j made this easy.</p>
<pre class="prettyprint">
  public Maze fromXml(File xmlFile) {
    SAXReader reader = new SAXReader();
    try {
      Document document = reader.read(xmlFile);
      return fromXml(document);
    } catch (DocumentException e) {
      throw new RuntimeException("Error reading file " +
        xmlFile.getAbsolutePath() + ".", e);
    }
  }

  public Maze fromXml(String xml) {   // For testing.
    try {
      Document document = DocumentHelper.parseText(xml);
      return fromXml(document);
    } catch (DocumentException e) {
      throw new RuntimeException("Error parsing xml string.", e);
    }
  }

  private Maze fromXml(Document document) {
    // To implement - see below...
  }
</pre>
<p>The second and final step in parsing is to implement the fromXml(Document) method. This is basically the inverse of the toXml(Maze) method above: I iterate through the document, converting each element to a Java object and the attributes / text to properties of the object.</p>
<pre class="prettyprint">
  private Maze fromXml(Document document) {
    Element root = document.getRootElement();

    int width = getElementIntAttribute(root, WIDTH_ATTRIBUTE);
    int height = getElementIntAttribute(root, HEIGHT_ATTRIBUTE);
    Maze maze = new Maze(width, height);
    maze.setDescription(root.getText());

    for (Object elementObj : root.elements(WALL_ELEMENT)) {
      Element element = (Element) elementObj;
      int startX = getElementIntAttribute(element, START_X_ATTRIBUTE);
      int startY = getElementIntAttribute(element, START_Y_ATTRIBUTE);
      int endX = getElementIntAttribute(element, END_X_ATTRIBUTE);
      int endY = getElementIntAttribute(element, END_Y_ATTRIBUTE);
      maze.addWall(startX, startY, endX, endY);
    }
    return maze;
  }

  private int getElementIntAttribute(
    Element element, String attributeName) {

    Attribute attribute = getNonNullAttributeForElement(element, attributeName);
    return Integer.parseInt(attribute.getValue());
  }

  private Attribute getNonNullAttributeForElement(
    Element element, String attributeName) {

    Attribute attribute = element.attribute(attributeName);
    if (attribute == null) {
      throw new RuntimeException("Element " + element.getName() +
        " missing attribute named " + attributeName + ".");
    }
    return attribute;
  }
</pre>
<p>The generated XML is provided below, with line breaks and indentation added for readability:</p>
<pre class="prettyprint">
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;maze width="5" height="4"&gt;
  A maze
  &lt;wall startX="1" startY="0" endX="1" endY="1"/&gt;
  &lt;wall startX="0" startY="2" endX="1" endY="2"/&gt;
  &lt;wall startX="1" startY="3" endX="1" endY="4"/&gt;
  &lt;wall startX="2" startY="1" endX="2" endY="3"/&gt;
  &lt;wall startX="2" startY="1" endX="3" endY="1"/&gt;
  &lt;wall startX="3" startY="3" endX="3" endY="4"/&gt;
  &lt;wall startX="3" startY="3" endX="4" endY="3"/&gt;
  &lt;wall startX="4" startY="2" endX="4" endY="4"/&gt;
  &lt;wall startX="4" startY="1" endX="5" endY="1"/&gt;
&lt;/maze&gt;
</pre>
<p>Overall, I was happy with my choice of the dom4j library. Thanks largely to the good documentation on its website, I was able to quickly learn and use the library for my project. I did have a couple of complaints. The API could be a little more helpful: I had to write the getElementIntAttribute() and getNonNullAttributeForElement() methods which were generic enough that they should have been part of the library. I also missed having an addAttribute() method that takes an integer primitive as an an attribute value. My other complaint is that dom4j uses checked exceptions (DocumentException) rather than unchecked exceptions which I generally prefer. </p>
<p>While dom4j worked well for me, I did have fairly simple requirements for the XML I was generating and parsing. With more complex object models, I could see a binding library requiring less effort to use (similar to the tradeoff between using raw JDBC versus an object-relational mapping library for database persistence). So I encourage you to think about your current and future requirements before making a similar choice.</p>
<p>The source code listed in this article is provided in the <em>Java Examples</em> project which can be downloaded from the <a href="http://www.basilv.com/psd/software">Software</a> page.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.basilv.com/psd/blog/2006/parsing-and-generating-xml-with-java/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

