Chapter 19: 'Reading and Writing RSS Feeds'


Download chapter 19: 'Reading and Writing RSS Feeds'

This chapter is excerpted from the book titled, Sams Teach Yourself Java 6 in 21 Days, 5th Edition, authored by Rogers Cadenhead and Laura Lemay, published May, 2006 by SAMS Publishing, ISBN 0-672-32943-3, Copyright 2007 SAMS Publishing. For more information, please visit:

Chapter Excerpt:

Modifying an XML Document

The next project, the DomainEditor application, makes several changes to the XML document that was just produced by the RssStarter application, feed.rss. The text enclosed by the link element is changed to "", and a new item element is added:


Using the nu.xom package, XML documents can be loaded into a tree from several sources: a File, InputStream, Reader, or a URL (which is specified as a String instead of a object).

The Builder class represents a SAX parser that can load an XML document into a Document object. Constructor methods can be used to specify a particular parser or let XOM use the first available parser from this list: Xerces 2, Crimson, Piccolo, GNU Aelfred, Oracle, XP, Saxon Aelfred, or Dom4J Aelfred. If none of these is found, the parser specified by the system property org.xml.sax.driver is used. Constructors also determine whether the parser is validating or nonvalidating.

The Builder() and Builder(true) constructors both use the default parser—most likely a version of Xerces. The presence of the Boolean argument true in the second constructor configures the parser to be validating. It would be nonvalidating otherwise. A validating parser throws a nu.xom.ValidityException if the XML document doesn't validate according to the rules of its document type definition.

The Builder object's build() method loads an XML document from a source and returns a Document object:

Builder builder = new Builder();
File xmlFile = new File("feed.rss");
Document doc =;

These statements load an XML document from the file feed.rss barring one of two problems: A nu.xom.ParseException is thrown if the file does not contain well-formed XML, and a is thrown if the input operation fails. Elements are retrieved from the tree by calling a method of their parent node.

A Document object's getRootElement() method returns the root element of the document:
Element root = doc.getRootElement();

In the XML document feed.rss, the root element is domains.

Elements with names can be retrieved by calling their parent node's getFirstChildElement() method with the name as a String argument:
Element channel = root.getFirstChildElement("channel");

This statement retrieves the channel element contained in the rss element (or null if that element could not be found). Like other examples, this is simplified by the lack of a namespace in the document; there are also methods where a name and namespace are arguments.

When several elements within a parent have the same name, the parent node's getChildElements() method can be used instead:
Elements children = channel.getChildElements()

The getChildElements() method returns an Elements object containing each of the elements. This object is a read-only list and does not change automatically if the parent node's contents change after getChildElements() is called.

Elements has a size() method containing an integer count of the elements it holds. This can be used in a loop to cycle through each element in turn beginning with the one at position 0. There's a get() method to retrieve each element; call it with the integer position of the element to be retrieved:
for (int i = 0; i < children.size(); i++) { Element link = children.get(i);

This for loop cycles through each child element of the channel element.

Elements without names can be retrieved by calling their parent node's getChild() method with one argument: an integer indicating the element's position within the parent node:
Text linkText = (Text) link.getChild(0);

This statement creates the Text object for the text "" found within the link element. Text elements always will be at position 0 within their enclosing parent. To work with this text as a string, call the Text object's getValue() method, as in this statement:
if (linkText.getValue().equals(""))
// ...

The DomainEditor application only modifies a link element enclosing the text "". The application makes the following changes: The text of the link element is deleted, the new text "" is added in its place, and then a new item element is added.

A parent node has two removeChild() methods to delete a child node from the document. Calling the method with an integer deletes the child at that position:
Element channel = domain.getFirstChildElement("channel");
Element link = dns.getFirstChildElement("link");

These statements would delete the Text object contained within the channel's first link element.

Calling the removeChild() method with a node as an argument deletes that particular node. Extending the previous example, the link element could be deleted with this statement:

Listing 19.4 shows the source code of the DomainEditor application.

LISTING 19.4 The Full Text of

1: import*;
2: import nu.xom.*;
4:   public class DomainEditor {
5:       public static void main(String[] arguments) throws IOException {
6:           try {
7:               // create a tree from the XML document feed.rss
8:               Builder builder = new Builder();
9:               File xmlFile = new File("feed.rss");
10:               Document doc =;
12:               // get the root element 
13:               Element root = doc.getRootElement();
15:               // get its 
16:               Element channel = root.getFirstChildElement("channel");
18:               // get its 
19:               Elements children = channel.getChildElements();
20:               for (int i = 0; i < children.size(); i++) {
22:                   // get a 
23:                   Element link = children.get(i);
25:                   // get its text
26:                   Text linkText = (Text) link.getChild(0);
28:                   // update any link matching a URL
29:                   if (linkText.getValue().equals(
30:                   "")) {
32:                       // update the link's text
33:                       link.removeChild(0);
34:                       link.appendChild("");
35:                   }
36:               }
38:               // create new elements and attributes to add
39:               Element item = new Element("item");
40:               Element itemTitle = new Element("title");
42:               // add them to the 
43:               itemTitle.appendChild(
44:                   "Fuzzy Zoeller Sues Over Libelous Wikipedia Page"
45:               );
46:               item.appendChild(itemTitle);
47:               channel.appendChild(item);
49:               // display the XML document
50:               System.out.println(doc.toXML());
51:         } catch (ParsingException pe) {
52:               System.out.println("Error parsing document: " + pe.getMessage());
53:               pe.printStackTrace();
54:               System.exit(-1);
55:         }
56:     }
57: }

The DomainEditor application displays the modified XML document to standard output, so it can be run with the following command to produce a file named feeds2.rss: java DomainEditor > feed2.rss

Chapter 19: 'Reading and Writing RSS Feeds'


This was first published in May 2007

Dig Deeper on SAP ABAP






Forgot Password?


Your password has been sent to: