circles.java
import java.awt.*;
import java.awt.event.*;
import org.w3c.dom.*;
import org.apache.xerces.parsers.DOMParser;
public class circles
{
static int numberFigures = 0;
static int x[] = new int[100];
static int y[] = new int[100];
static int radius[] = new int[100];
public static void displayDocument(String
uri)
{
try {
DOMParser parser = new DOMParser();
parser.parse(uri);
Document document = parser.getDocument();
display(document);
} catch (Exception e)
{
e.printStackTrace(System.err);
}
}
public static void display(Node node)
{
if (node == null) {
return;
}
int type =
node.getNodeType();
if (node.getNodeType()
== Node.DOCUMENT_NODE) {
display(((Document)node).getDocumentElement());
}
if (node.getNodeType()
== Node.ELEMENT_NODE) {
if (node.getNodeName().equals("CIRCLE")) {
NamedNodeMap attrs = node.getAttributes();
x[numberFigures]
=
Integer.parseInt((String)attrs.getNamedItem("X").getNodeValue());
y[numberFigures] =
Integer.parseInt((String)attrs.getNamedItem("Y").getNodeValue());
radius[numberFigures] =
Integer.parseInt((String)attrs.getNamedItem("RADIUS").getNodeValue());
numberFigures++;
}
NodeList childNodes = node.getChildNodes();
if (childNodes != null) {
int length = childNodes.getLength();
for (int loopIndex = 0; loopIndex < length; loopIndex++) {
display(childNodes.item(loopIndex));
}
}
}
}
public static void main(String args[])
{
displayDocument(args[0]);
AppFrame f = new
AppFrame(numberFigures, x, y, radius);
f.setSize(400,
400);
f.addWindowListener(new
WindowAdapter() {public void
windowClosing(WindowEvent e) {System.exit(0);}});
f.show();
}
}
class AppFrame extends Frame
{
int numberFigures;
int[] xValues;
int[] yValues;
int[] radiusValues;
public AppFrame(int number, int[] x, int[] y,
int[] radius)
{
numberFigures =
number;
xValues = x;
yValues = y;
radiusValues =
radius;
}
public void paint(Graphics g)
{
for(int loopIndex = 0;
loopIndex < numberFigures; loopIndex++){
g.drawOval(xValues[loopIndex], yValues[loopIndex],
radiusValues[loopIndex],
radiusValues[loopIndex]);
}
}
}
Navigating in XML Documents
As you saw earlier in Table 11.4, the Node interface contains all
the standard W3C DOM methods for navigating in a document that we've
already used with JavaScript in Chapter 7, including getNextSibling,
getPreviousSibling, getFirstChild, getLastChild, and getParent. You
can put those methods to work here as easily as in Chapter 7; for
example, here's the XML document that we navigated through in Chapter
7, meetings.xml:
<?xml version="1.0"?>
<MEETINGS>
<MEETING TYPE="informal">
<MEETING_TITLE>XML In
The Real World</MEETING_TITLE>
<MEETING_NUMBER>2079</MEETING_NUMBER>
<SUBJECT>XML</SUBJECT>
<DATE>6/1/2002</DATE>
<PEOPLE>
<PERSON ATTENDANCE="present">
<FIRST_NAME>Edward</FIRST_NAME>
<LAST_NAME>Samson</LAST_NAME>
</PERSON>
<PERSON ATTENDANCE="absent">
<FIRST_NAME>Ernestine</FIRST_NAME>
<LAST_NAME>Johnson</LAST_NAME>
</PERSON>
<PERSON ATTENDANCE="present">
<FIRST_NAME>Betty</FIRST_NAME>
<LAST_NAME>Richardson</LAST_NAME>
</PERSON>
</PEOPLE>
</MEETING>
</MEETINGS>
In Chapter 7, we navigated through this document to display the
third person's name, and I'll do the same here. The main difference
between the XML for Java and the JavaScript implementations in this
case is that the XML for Java implementation treats all text as text
nodes-including the spacing used to indent meetings.xml. This means
that I can use essentially the same code to navigate through the
document here that we used in Chapter 7, bearing in mind that we must
step over the text nodes which only contain indentation text. Here's
what that looks like in a program named nav.java:
import org.w3c.dom.*;
import org.apache.xerces.parsers.DOMParser;
public class nav
{
public static void displayDocument(String
uri)
{
try {
DOMParser parser = new DOMParser();
parser.parse(uri);
Document document = parser.getDocument();
display(document);
} catch (Exception e)
{
e.printStackTrace(System.err);
}
}
public static void display(Node node)
{
Node textNode;
Node meetingsNode =
((Document)node).getDocumentElement();
textNode =
meetingsNode.getFirstChild();
Node meetingNode =
textNode.getNextSibling();
textNode =
meetingNode.getLastChild();
Node peopleNode =
textNode.getPreviousSibling();
textNode =
peopleNode.getLastChild();
Node personNode =
textNode.getPreviousSibling();
textNode =
personNode.getFirstChild();
Node first_nameNode =
textNode.getNextSibling();
textNode =
first_nameNode.getNextSibling();
Node last_nameNode =
textNode.getNextSibling();
System.out.println("Third name: " +
first_nameNode.getFirstChild().getNodeValue() + ' '
+ last_nameNode.getFirstChild().getNodeValue());
}
public static void main(String args[])
{
displayDocument("meetings.xml");
}
}
And here are the results of this program:
%java nav
Third name: Betty Richardson
Ignoring Whitespace
You can eliminate the indentation spaces, called "ignorable"
whitespace, if you want. In that case, you must provide the XML for
Java parser some way of checking the grammar of your XML document so
that it knows what kind of whitespace it may ignore, and you can do
that by giving the document a DTD:
<?xml version="1.0"?>
<!DOCTYPE MEETINGS [
<!ELEMENT MEETINGS (MEETING*)>
<!ELEMENT MEETING
(MEETING_TITLE,MEETING_NUMBER,SUBJECT,DATE,PEOPLE*)>
<!ELEMENT MEETING_TITLE (#PCDATA)>
<!ELEMENT MEETING_NUMBER (#PCDATA)>
<!ELEMENT SUBJECT (#PCDATA)>
<!ELEMENT DATE (#PCDATA)>
<!ELEMENT FIRST_NAME (#PCDATA)>
<!ELEMENT LAST_NAME (#PCDATA)>
<!ELEMENT PEOPLE (PERSON*)>
<!ELEMENT PERSON (FIRST_NAME,LAST_NAME)>
<!ATTLIST MEETING
TYPE CDATA #IMPLIED>
<!ATTLIST PERSON
ATTENDANCE CDATA #IMPLIED>
]>
<MEETINGS>
<MEETING TYPE="informal">
<MEETING_TITLE>XML In
The Real World</MEETING_TITLE>
<MEETING_NUMBER>2079</MEETING_NUMBER>
<SUBJECT>XML</SUBJECT>
<DATE>6/1/2002</DATE>
<PEOPLE>
<PERSON ATTENDANCE="present">
<FIRST_NAME>Edward</FIRST_NAME>
<LAST_NAME>Samson</LAST_NAME>
</PERSON>
<PERSON ATTENDANCE="absent">
<FIRST_NAME>Ernestine</FIRST_NAME>
<LAST_NAME>Johnson</LAST_NAME>
</PERSON>
<PERSON ATTENDANCE="present">
<FIRST_NAME>Betty</FIRST_NAME>
<LAST_NAME>Richardson</LAST_NAME>
</PERSON>
</PEOPLE>
</MEETING>
</MEETINGS>
Now I call the parser method setIncludeIgnorableWhitespace with a
value of false to turn off ignorable whitespace, and I don't have to
worry about the indentation spaces showing up as text nodes, which
makes the code considerably shorter:
import org.w3c.dom.*;
import org.apache.xerces.parsers.DOMParser;
public class nav
{
public static void displayDocument(String
uri)
{
try {
DOMParser parser = new DOMParser();
parser.setIncludeIgnorableWhitespace(false);
parser.parse(uri);
Document document = parser.getDocument();
display(document);
} catch (Exception e)
{
e.printStackTrace(System.err);
}
}
public static void display(Node node)
{
Node meetingsNode =
((Document)node).getDocumentElement();
Node meetingNode =
meetingsNode.getFirstChild();
Node peopleNode =
meetingNode.getLastChild();
Node personNode =
peopleNode.getLastChild();
Node first_nameNode =
personNode.getFirstChild();
Node last_nameNode =
first_nameNode.getNextSibling();
System.out.println("Third name: " +
first_nameNode.getFirstChild().getNodeValue() + ' '
+ last_nameNode.getFirstChild().getNodeValue());
}
public static void main(String args[])
{
displayDocument("meetings.xml");
}
}
Modifying XML Documents
As you saw earlier in Table 11.4, the Node interface contains a
number of methods for modifying documents by adding or removing
nodes. These methods include appendChild, insertBefore, removeChild,
replaceChild, and so on. You can use these methods to modify XML
documents on the fly.
If you do modify a document, however, you still have to write it
out. (In Chapter 7, we couldn't do that using JavaScript in a
browser, so I sent the whole document to an ASP script that echoed it
back to be displayed in the browser.) The XML for Java packages do
support an interface named Serializer that you can use to serialize
(store) documents. However, that interface is not included in the
standard JAR files that we've already downloaded-in fact, it's easy
enough to simply store the modified XML document ourselves because we
print out that document anyway. Instead of using System.out.println
to display the modified document on the console, I'll use a Java
FileWriter object to write that document to disk.
In this example, I'll assume that all the people listed in
customer.xml (you can see this document at the beginning of this
chapter) are experienced XML programmers. In addition to the
<FIRST_NAME> and <LAST_NAME> elements, I'll give each of
them XML as a middle name by adding a <MIDDLE_NAME> element.
Like <FIRST_NAME> and <LAST_NAME>, <MIDDLE_NAME>
will be a child element of the <NAME> element:
<NAME>
<LAST_NAME>
Jones
</LAST_NAME>
<FIRST_NAME>
Polly
</FIRST_NAME>
<MIDDLE_NAME>
XML
</MIDDLE_NAME>
</NAME>
Adding a <MIDDLE_NAME> element to every <NAME> element
is easy enough to do-all I have to do is make sure that we're parsing
the <NAME> element, and then use the createElement method to
create a new element named <MIDDLE_NAME>:
case Node.ELEMENT_NODE: {
if(node.getNodeName().equals("NAME")) {
Element
middleNameElement = document.createElement("MIDDLE_NAME");
.
.
.
Because all text is stored in text nodes, I also create a new text
node with the createTextNode method to hold the text XML:
case Node.ELEMENT_NODE: {
if(node.getNodeName().equals("NAME")) {
Element
middleNameElement = document.createElement("MIDDLE_NAME");
Text textNode =
document.createTextNode("XML");
.
.
.
Now I can append the text node to the new element with
appendChild:
case Node.ELEMENT_NODE: {
if(node.getNodeName().equals("NAME")) {
Element
middleNameElement = document.createElement("MIDDLE_NAME");
Text textNode =
document.createTextNode("XML");
middleNameElement.appendChild(textNode);
.
.
.
Finally, I append the new element to the <NAME> node, like
this:
case Node.ELEMENT_NODE: {
if(node.getNodeName().equals("NAME")) {
Element
middleNameElement = document.createElement("MIDDLE_NAME");
Text textNode =
document.createTextNode("XML");
middleNameElement.appendChild(textNode);
node.appendChild(middleNameElement);
}
.
.
.
Using this code, I'm able to modify the document in memory. As
before, the lines of this document are stored in the array
displayStrings, and I can write that array out to a file called
customer2.xml. To do that, I use the Java FileWriter class, which
writes text stored as character arrays in files. To create those
character arrays, I can use the Java String object's handy
toCharArray method, like this:
public static void main(String args[])
{
displayDocument(args[0]);
try {
FileWriter filewriter =
new FileWriter("customer2.xml");
for(int loopIndex = 0;
loopIndex < numberDisplayLines; loopIndex++){
filewriter.write(displayStrings[loopIndex].toCharArray());
filewriter.write('\n');
}
filewriter.close();
}
catch (Exception e) {
e.printStackTrace(System.err);
}
}
That's all there is to it; after running this code, this is the
result, customer2.xml, complete with the new <MIDDLE_NAME>
elements:
<?xml version="1.0" encoding="UTF-8"?>
<DOCUMENT>
<CUSTOMER>
<NAME>
<LAST_NAME>
Smith
</LAST_NAME>
<FIRST_NAME>
Sam
</FIRST_NAME>
<MIDDLE_NAME>
XML
</MIDDLE_NAME>
</NAME>
<DATE>
October 15, 2001
</DATE>
<ORDERS>
<ITEM>
<PRODUCT>
Tomatoes
</PRODUCT>
<NUMBER>
8
</NUMBER>
<PRICE>
$1.25
</PRICE>
</ITEM>
<ITEM>
<PRODUCT>
Oranges
</PRODUCT>
<NUMBER>
24
</NUMBER>
<PRICE>
$4.98
</PRICE>
</ITEM>
</ORDERS>
</CUSTOMER>
<CUSTOMER>
<NAME>
<LAST_NAME>
Jones
</LAST_NAME>
<FIRST_NAME>
Polly
</FIRST_NAME>
<MIDDLE_NAME>
XML
</MIDDLE_NAME>
</NAME>
<DATE>
October 20, 2001
</DATE>
<ORDERS>
<ITEM>
<PRODUCT>
Bread
</PRODUCT>
<NUMBER>
12
</NUMBER>
<PRICE>
$14.95
</PRICE>
</ITEM>
<ITEM>
<PRODUCT>
Apples
</PRODUCT>
<NUMBER>
6
</NUMBER>
<PRICE>
$1.50
</PRICE>
</ITEM>
</ORDERS>
</CUSTOMER>
<CUSTOMER>
<NAME>
<LAST_NAME>
Weber
</LAST_NAME>
<FIRST_NAME>
Bill
</FIRST_NAME>
<MIDDLE_NAME>
XML
</MIDDLE_NAME>
</NAME>
<DATE>
October 25, 2001
</DATE>
<ORDERS>
<ITEM>
<PRODUCT>
Asparagus
</PRODUCT>
<NUMBER>
12
</NUMBER>
<PRICE>
$2.95
</PRICE>
</ITEM>
<ITEM>
<PRODUCT ID="5231" TYPE="3133">
Lettuce
</PRODUCT>
<NUMBER>
6
</NUMBER>
<PRICE>
$11.50
</PRICE>
</ITEM>
</ORDERS>
</CUSTOMER>
</DOCUMENT>
You can find the code for this example, XMLWriter.java, in Listing
11.5.
XMLWriter.java
import java.awt.*;
import java.io.*;
import java.awt.event.*;
import org.w3c.dom.*;
import org.apache.xerces.parsers.DOMParser;
import org.apache.xerces.*;
public class XMLWriter
{
static String displayStrings[] = new
String[1000];
static int numberDisplayLines = 0;
static Document document;
static Node c;
public static void displayDocument(String
uri)
{
try {
DOMParser parser = new DOMParser();
parser.parse(uri);
document = parser.getDocument();
display(document, "");
} catch (Exception e)
{
e.printStackTrace(System.err);
}
}
public static void display(Node node, String
indent)
{
if (node == null) {
return;
}
int type =
node.getNodeType();
switch (type) {
case Node.DOCUMENT_NODE: {
displayStrings[numberDisplayLines] = indent;
displayStrings[numberDisplayLines] +=
"<?xml version=\"1.0\" encoding=\""+
"UTF-8" + "\"?>";
numberDisplayLines++;
display(((Document)node).getDocumentElement(), "");
break;
}
case Node.ELEMENT_NODE: {
if(node.getNodeName().equals("NAME")) {
Element middleNameElement =
document.createElement("MIDDLE_NAME");
Text textNode = document.createTextNode("XML");
middleNameElement.appendChild(textNode);
node.appendChild(middleNameElement);
}
displayStrings[numberDisplayLines] = indent;
displayStrings[numberDisplayLines] += "<";
displayStrings[numberDisplayLines] += node.getNodeName();
int length = (node.getAttributes() != null) ?
node.getAttributes().getLength() : 0;
Attr attributes[] = new Attr[length];
for (int loopIndex = 0; loopIndex < length; loopIndex++) {
attributes[loopIndex] =
(Attr)node.getAttributes().item(loopIndex);
}
for (int loopIndex = 0; loopIndex < attributes.length;
loopIndex++) {
Attr attribute = attributes[loopIndex];
displayStrings[numberDisplayLines] += " ";
displayStrings[numberDisplayLines] += attribute.getNodeName();
displayStrings[numberDisplayLines] += "=\"";
displayStrings[numberDisplayLines] += attribute.getNodeValue();
displayStrings[numberDisplayLines] += "\"";
}
displayStrings[numberDisplayLines]+=">";
numberDisplayLines++;
NodeList childNodes = node.getChildNodes();
if (childNodes != null) {
length = childNodes.getLength();
indent += " ";
for (int loopIndex = 0; loopIndex < length; loopIndex++ ) {
display(childNodes.item(loopIndex), indent);
}
}
break;
}
case Node.CDATA_SECTION_NODE: {
displayStrings[numberDisplayLines] = indent;
displayStrings[numberDisplayLines] += "<![CDATA[";
displayStrings[numberDisplayLines] += node.getNodeValue();
displayStrings[numberDisplayLines] += "]]>";
numberDisplayLines++;
break;
}
case Node.TEXT_NODE: {
displayStrings[numberDisplayLines] = indent;
String newText = node.getNodeValue().trim();
if(newText.indexOf("\n") < 0 && newText.length() > 0)
{
displayStrings[numberDisplayLines] += newText;
numberDisplayLines++;
}
break;
}
case Node.PROCESSING_INSTRUCTION_NODE: {
displayStrings[numberDisplayLines] = indent;
displayStrings[numberDisplayLines] += "<?";
displayStrings[numberDisplayLines] += node.getNodeName();
String text = node.getNodeValue();
if (text != null && text.length() > 0) {
displayStrings[numberDisplayLines] += text;
}
displayStrings[numberDisplayLines] += "?>";
numberDisplayLines++;
break;
}
}
if (type ==
Node.ELEMENT_NODE) {
displayStrings[numberDisplayLines] = indent.substring(0,
indent.length() - 4);
displayStrings[numberDisplayLines] += "</";
displayStrings[numberDisplayLines] += node.getNodeName();
displayStrings[numberDisplayLines] += ">";
numberDisplayLines++;
indent += " ";
}
}
public static void main(String args[])
{
displayDocument(args[0]);
try {
FileWriter filewriter = new FileWriter("customer2.xml");
for(int loopIndex = 0; loopIndex < numberDisplayLines;
loopIndex++){
filewriter.write(displayStrings[loopIndex].toCharArray());
filewriter.write('\n');
}
filewriter.close();
}
catch (Exception e)
{
e.printStackTrace(System.err);
}
}
}
As you see, there's a lot of power in XML for Java. In fact,
there's another way to do all this besides using the DOM. It's called
SAX, and I'll take a look at it in the next
chapter.><><Chapter 11 Java and the XML
DOM><><Getting XML for Java><><Chapter
11 TopXML : Java and the XML DOM><><Creating a
Parser><continues .><><Chapter 11 Java and
the XML DOM><><Creating a
Parser><continues><><Chapter 11 Java and the
XML DOM><><Creating a Parser><><Chapter
11 TopXML : Java and the XML DOM><><Creating a
Parser><Method
Description><continues><><Chapter 11 Java and
the XML DOM><Table 11.2 Continued
Method
Description><><Creating a
Parser><Method
Description><continues><><Chapter 11 Java and
the XML DOM><Table 11.2 Continued
Method
Description><><Creating a
Parser><Method
Description><><Chapter 11 Java and the XML
DOM><><Creating a
Parser><Method
Description><><Chapter 11 Java and the XML
DOM><><Creating a
Parser><Method
Description><><Chapter 11 Java and the XML
DOM><><Displaying an Entire
Document><><Chapter 11 Java and the XML
DOM><><Displaying an Entire
Document><><Chapter 11 Java and the XML
DOM><><Displaying an Entire
Document><><Chapter 11 Java and the XML
DOM><><Displaying an Entire
Document><><Chapter 11 Java and the XML
DOM><><Displaying an Entire
Document><><Chapter 11 Java and the XML
DOM><><Displaying an Entire
Document><continues><><Chapter 11 Java and
the XML DOM><Listing
11.1 Continued><><Filtering XML
Documents><continues .><><Chapter 11 Java and
the XML DOM><><Filtering XML
Documents><continues><><Chapter 11 Java and
the XML DOM><Listing
11.2 Continued><><Creating a Windowed
Browser><><Chapter 11 Java and the XML
DOM><><Creating a Windowed Browser><><Chapter
11 TopXML : Java and the XML DOM><><Creating a Windowed
Browser><continues><><Chapter 11 Java and the
XML DOM><Listing
11.3 Continued><><Creating a Graphical
Browser><continues .><><Chapter 11 Java and
the XML DOM><><Creating a Graphical
Browser><><Chapter 11 Java and the XML
DOM><><Creating a Graphical
Browser><continues><><Chapter 11 Java and the
XML DOM><Listing
11.4 Continued><><Navigating in XML
Documents><continues .><><Chapter 11 Java and
the XML DOM><><Navigating in XML
Documents><continues .><><Chapter 11 Java and
the XML DOM><><Modifying XML Documents><continues
.><><Chapter 11 Java and the XML
DOM><><Modifying XML Documents><continues
.><><Chapter 11 Java and the XML
DOM><><Modifying XML
Documents><continues><><Chapter 11 Java and
the XML DOM><Listing
11.5 Continued><><Modifying XML
Documents><continues><><Chapter 11 Java and
the XML DOM><Listing 11.4 Continued>