[jdom-interest] Document root element is missing.
David Parker
dlparker at facstaff.wisc.edu
Tue Apr 1 08:26:23 PST 2003
Skipped content of type multipart/alternative-------------- next part --------------
import java.io.*;
import org.jdom.*;
import java.util.*;
/**
*
* @author dp8
* @version 1.0.1
* Created on Mar 31, 2003
*
* Navigating JDOM Trees
* Once you?ve parsed a document and formed a Document object, you?ll probably want to search it
* to select out those parts of it your program is interested in.
* In JDOM, most navigation takes place through the methods of the Element class.
* The complete children of each Element are available as a java.util.List returned by the getContent() method.
* Just the child elements of each Element are available in a java.util.List returned by the getChildren() method.
* (Yes, the terminology is a little confusing here. This is a case where JDOM is marching out of step
* with the rest of the XML world.
* <b>JDOM uses the word children to refer only to child elements.</b>)
*
* Because JDOM uses the Java Collections API to manage the tree, it is simultaneously too polymorphic
* (everything?s an object and must be cast to the right type before you can use it)
* and not polymorphic enough (there?s no useful generic interface or superclass for navigation
* such as DOM?s Node class.)
*
* <b>Consequently, you?re going to find yourself doing numerous tests with instanceof and casting to the determined type.</b>
* Furthermore, there?s no standard traversal API as there is in DOM to help you avoid reinventing the wheel every time
* you need to walk a tree or iterate a document.
*
* There is a Filter interface that can simplify some of the polymorphism and casting issues a little,
* but it still won?t let you walk more than one level down the tree at a time.
*
*/
public class QtiReader {
/*
* String constants that are important nodes in the QTI xml file.
*/
private static String QUESTESTINTEROP = "questestinterop";
private static String ITEM = "item";
private static String PRESENTATION = "presentation";
private static String FLOW = "flow";
private static String RESPONSE_LID = "response_lid";
private static String MATERIAL = "material";
private static String MATTEXT = "mattext";
private static String RENDER_CHOICE = "render_choice";
private static String FLOW_LABEL = "flow_label";
private static String RESPONSE_LABEL = "response_label";
private static String FLOW_MAT = "flow_mat";
private static String RESPROCESSING = "resprocessing";
private static String OUTCOMES = "outcomes";
private static String DECVAR = "decvar";
private static String RESPCONDITION = "respcondition";
private static String CONDITIONVAR = "conditionvar";
private static String VAREQUAL = "varequal";
private static String SETVAR = "setvar";
private static String DISPLAYFEEDBACK = "displayfeedback";
private static String ITEMFEEDBACK = "itemfeedback";
private int request_count = 0;
private int response_count = 0;
private java.lang.String input = "C:\\src\\in-utf-8.xml";
private java.lang.String output = "C:\\src\\out-utf-8.html";
private org.jdom.Document doc = null;
private org.jdom.Element root = null;
public java.lang.StringBuffer html = new java.lang.StringBuffer();
/**
* This <code>QtiReader</code> constructor with no parameters and
* is called from main() and uses the hard coded input and output files.
*/
public QtiReader() {
}//constructor
/**
* <code>QtiReader</code> constructor has two parameters;
* that are the pathname of the input and output files.
* It calls the setters for each property.
* @param in string with the input pathname
* @param out string with the output pathname
*/
public QtiReader(String in, String out) {
setInput(in);
setOutput(out);
}//constructor
/**
* <code>main</code>is implemented so that it can be tested as a standalone application.
* I call the default constructor with no parameters. The input and output are hard coded.
* If you change them to the relative pathname space then make sure theyare in the same
* directory as the class.
* <ol>
* <li>Instanciate the QtiReader class.</li>
* <li>Instanciate the QtiReader class.</li>
* <li>Instanciate the QtiReader class.</li>
* <li>Instanciate the QtiReader class.</li>
* </ol>
* @param args
*/
public static void main(String[] args) {
String in = "";
QtiReader qtireader = new QtiReader();
qtireader.readUtf8Input();
if (qtireader.root != null) {
qtireader.whichChild(qtireader.root);
qtireader.dumpIT();
qtireader.writeUtf8Output();
}
}
/**
* <code>readUtf8Input</code> decodes the byte stream into a character stream
* and returns a java.io.String.
* <ol>
* <li>Opens a connection to an actual file.</li>
* <li>Obtains input bytes from a file in a file system.</li>
* <li>Creates an InputStreamReader that users the named character set.</li>
* <li>InputStreamReader is a bridge between the byte stream to character stream.</li>
* <li>It reads bytes and decodes them into characters using the specified character set.</li>
* <li>Create a buffering character input stream that uses the default buffer size.</li>
* <li>Reads a single character this method will block until a character is available,
* an I/O error occurs, or the end of the stream is reached.</li>
* </ol>
* @exception JDOMException Indicates a well-formedness error
* @exception UnsupportedEncodingException, if the character encoding is not supported.
* @exception FileNotFoundException, if the fails to open a file with the given pathname.
* @exception IOException, the general io exception handler.
* @exception Exception, if a condition exists that the method could not handle.
* @return The reader to the QTI character stream as a java.io.String.
*/
private void readUtf8Input() {
org.jdom.input.SAXBuilder builder = new org.jdom.input.SAXBuilder();
//org.jdom.input.SAXBuilder builder = new org.jdom.input.SAXBuilder("org.apache.xerces.parsers.SAXParser");
try {
// Opens a connection to an actual file.
// Obtains input bytes from a file in a file system.
java.io.FileInputStream fis = new java.io.FileInputStream(this.input);
// Creates an InputStreamReader that users the named character set.
// InputStreamReader is a bridge between the byte stream to character stream.
// It reads bytes and decodes them into characters using the specified character set.
java.io.InputStreamReader isr = new java.io.InputStreamReader(fis, "UTF8");
// Create a buffering character input stream that uses the default buffer size.
// Class for reading character streams.
java.io.Reader reader = new java.io.BufferedReader(isr);
System.out.println("past - this.reader");
int ch;
java.lang.StringBuffer buffer = new java.lang.StringBuffer();
//System.out.println("\n\n\t*** " + reader.read() + " ***\n\n\n");
while ((ch = reader.read()) > -1) {
buffer.append((char)ch);
}
System.out.println("past - while loop, buffer length is " + buffer.length());
System.out.println("Dumping " + input + "\n" + buffer.toString());
this.doc = builder.build(buffer.toString());
System.out.println("past - this.doc");
this.root = this.doc.getRootElement();
System.out.println("past - this.root");
reader.close();
// indicates a well-formedness error
} catch (org.jdom.JDOMException jde) {
System.out.println("\n\n\nJDOMException: " + input + " is not well-formed.\n");
System.out.println(jde.toString());
System.out.println(jde.getMessage());
//jde.printStackTrace();
} catch (java.io.UnsupportedEncodingException use) {
use.printStackTrace();
} catch (java.io.FileNotFoundException fnfe) {
fnfe.printStackTrace();
} catch (java.lang.Exception e) {
e.printStackTrace();
} finally { }
}
/**
*
* @param c
* @return
*/
private String escape(char c) {
StringBuffer b = new StringBuffer();
for (int i = 0; i < 4; i++) {
b.append(Integer.toHexString(c & 0x000F).toUpperCase());
c >>>= 4;
}
b.append("u\\");
return b.reverse().toString();
}
/**
*
* @param s
*/
private void decode(String s) {
char[] ch = s.toCharArray();
for (int i = 0; i < ch.length; i++) {
if(ch[i] < 128) {
System.out.print(ch[i]);
} else {
System.out.print(this.escape(ch[i]));
}
}
System.out.println();
}
/**
* <code>writeUtf8Output</code> take a string that is the QTI xml text
* that needs to be persisted tothe file system.
* <ol>
* <li>Creates an output file stream to write to the file with the specified name.</li>
* <li>Creates an OutputStreamWriter that uses the named character set.</li>
* <li>Take the stringbuffer were the HTML has been appened and send it to the writer().
* </ol>
*
* @exception UnsupportedEncodingException, if the character encoding is not supported.
* @exception FileNotFoundException, if the fails to open a file with the given pathname.
* @exception IOException, the general io exception handler.
* @exception Exception, if a condition exists that the method could not handle.
*/
private void writeUtf8Output() {
java.io.FileOutputStream fos = null;
java.io.Writer out = null;
try {
// Creates an output file stream to write to the file with the specified name.
fos = new FileOutputStream(output);
// Creates an OutputStreamWriter that uses the named character set.
out = new OutputStreamWriter(fos, "UTF8");
// The OutputStreamWriter is a bridge from charater streams to byte streams.
// The HTML character stream is written to the file system.
out.write(this.html.toString());
out.close();
fos.close();
} catch (java.io.UnsupportedEncodingException use) {
use.printStackTrace();
} catch (java.io.FileNotFoundException fnfe) {
fnfe.printStackTrace();
} catch (java.io.IOException ioe) {
ioe.printStackTrace();
} catch (java.lang.Exception e) {
e.printStackTrace();
} finally { }
}
/**
*
* @param current
*/
public void whichChild(Element current) {
String node = current.getName();
String attribute = "";
String text = "";
String title = "";
if ( node.equals(QUESTESTINTEROP) ) {
System.out.println(node);
this.html.append("\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
this.html.append("\n<table xmlns:fo=\"http://www.w3.org/1999/XSL/Format\" width=\"100%\" border=\"1\" cellspacing=\"1\" cellpadding=\"1\">");
listChildren(current);
this.html.append("\n</table>");
return;
} else if (node.equals(ITEM)) {
System.out.println("\t"+node);
title = current.getAttribute("title").getValue();
listChildren(current);
return;
} else if (node.equals(PRESENTATION)) {
//This will return the actual textual value of this Attribute.
//This will include all text within the quotation marks.
attribute = current.getAttribute("label").getValue();
System.out.println("\t\t"+node+ "\t" +attribute);
listChildren(current);
return;
} else if (node.equals(FLOW)) {
System.out.println("\t\t\t"+node);
listChildren(current);
return;
} else if (node.equals(RESPONSE_LID)) {
request_count++;
text = current.getChild(MATERIAL).getChild(MATTEXT).getText();
this.decode(current.getChild(MATERIAL).getChild(MATTEXT).getText());
System.out.println("\n\t\t\t\t"+node+ " count is " + request_count+ " : " + text);
if (response_count!=0 && response_count!=0) {
response_count=0;
appendCloseTable();
}
appendQuestion(text);
listChildren(current);
return;
} else if (node.equals(RENDER_CHOICE)) {
System.out.println("\t\t\t\t"+node);
listChildren(current);
return;
} else if (node.equals(FLOW_LABEL)) {
System.out.println("\t\t\t\t"+node);
listChildren(current);
return;
} else if (node.equals(RESPONSE_LABEL)) {
System.out.println("\t\t\t\t"+node);
listChildren(current);
return;
} else if (node.equals(FLOW_MAT)) {
response_count++;
text = current.getChild(MATERIAL).getChild(MATTEXT).getText();
this.decode(current.getChild(MATERIAL).getChild(MATTEXT).getText());
System.out.println("\t\t\t\t"+node+ " response count is " + response_count+ " : " + text);
appendChoice(text);
listChildren(current);
return;
} else if (node.equals(RESPROCESSING)) {
appendCloseTable();
return;
} else {
return;
}
}//whichChild()
/**
*
* @param current
*/
public void listChildren(Element current) {
try {
List children = current.getChildren();
Iterator iterator = children.iterator();
while (iterator.hasNext()) {
Element child = (Element) iterator.next();
whichChild(child);
}
} catch (java.util.NoSuchElementException nsee) {
System.out.println("java.util.NoSuchElementException\n\t ");
System.out.print("\n\t" +nsee.getMessage()+ "\n\t" + nsee.toString());
} catch ( Exception e) {
System.out.println("Exception:\n ");
System.out.println("Exception:toString()\n\t " + e.toString());
}
}//listChildren()
//****
//**** HTML strings
//****
//****
public void appendHead(Element current) {
this.html.append("\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
this.html.append("\n<table xmlns:fo=\"http://www.w3.org/1999/XSL/Format\" width=\"100%\" border=\"1\" cellspacing=\"1\" cellpadding=\"1\">");
listChildren(current);
this.html.append("\n</table>");
}
public void appendQuestion(String text) {
this.html.append("\n <table width=\"100%\" border=\"1\" cellspacing=\"1\" cellpadding=\"1\">");
this.html.append("\n <tr>");
this.html.append("\n <td>");
this.html.append("\n <table width=\"100%\" border=\"1\" cellspacing=\"1\" cellpadding=\"1\">");
this.html.append("\n <tr>");
this.html.append("\n <td width=\"1%\"> . </td>");
this.html.append("\n <td width=\"3%\"> . </td>");
this.html.append("\n <td width=\"96%\">" +text+ "</td>");
this.html.append("\n </tr>");
this.html.append("\n </table>");
this.html.append("\n </td>");
this.html.append("\n </tr>");
this.html.append("\n <tr>");
this.html.append("\n <td>");
this.html.append("\n <table width=\"100%\" border=\"1\" cellspacing=\"1\" cellpadding=\"1\">");
}
public void appendOpenTable(Element current) {
listChildren(current);
this.html.append("\n </table>");
this.html.append("\n </td>");
this.html.append("\n </tr>");
//this.html.append("\n </table>");
}
public void appendChoice(String text) {
this.html.append("\n <tr>");
this.html.append("\n <td width=\"1%\"> . </td>");
this.html.append("\n <td width=\"3%\"> . </td>");
this.html.append("\n <td width=\"4%\"> . </td>");
this.html.append("\n <td width=\"92%\">" +text+ "</td>");
this.html.append("\n </tr>");
}
public void appendCloseTable() {
this.html.append("\n </table>");
this.html.append("\n </td>");
this.html.append("\n </tr>");
}
public void dumpIT() {
System.out.println("**************");
System.out.println(this.html.toString());
System.out.println("**************");
}
/**
*
* @param s is the the pathname of the input file.
*/
public void setInput(String s) {
this.input = s;
}
/**
*
* @param s is the the pathname of the output file.
*/
public void setOutput(String s) {
this.output = s;
}
/**
*
* @return the pathname of the input file.
*/
public String getInput() {
return this.input;
}
/**
*
* @return the pathname of the output file.
*/
public String getOutput() {
return this.output;
}
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: in-utf-8.xml
Type: application/xml
Size: 2163 bytes
Desc: not available
Url : http://jdom.org/pipermail/jdom-interest/attachments/20030401/2d1c1851/in-utf-8.rdf
More information about the jdom-interest
mailing list